XdmfWeb
XdmfWikiDB
http://www.xdmf.org/index.php/Main_Page
MediaWiki 1.39.11
first-letter
Media
Special
Talk
User
User talk
XdmfWeb
XdmfWeb talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Main Page
0
1
1
2007-04-24T15:29:48Z
MediaWiki default
0
wikitext
text/x-wiki
<big>'''MediaWiki has been successfully installed.'''</big>
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
928e1deea259c70afc3513c66f29f3fcd740d8bf
2
1
2007-05-03T12:44:36Z
128.63.127.201
0
/* Getting started */
wikitext
text/x-wiki
<big>'''MediaWiki has been successfully installed.'''</big>
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
[[XDMF Model and Format]]XdmfFormat.html
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
d9be7250556b620ada857dc14b218e9dc1c4d5e4
3
2
2007-05-03T12:49:51Z
128.63.127.201
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
[[XDMF Model and Format]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
e67842b4092bb1445b048f789bcf6aae1951c8a6
4
3
2007-05-03T12:50:09Z
128.63.127.201
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
[[XDMF Model and Format]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
363ff868419bd412806f3b4b350ee8f98271869f
11
4
2007-05-03T16:11:24Z
128.63.127.201
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
[[XDMF Model and Format]]
[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
54ee466d686258b8336f3c59f3dd661427b505b1
12
11
2007-05-03T16:11:38Z
128.63.127.201
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
[[XDMF Model and Format]]
[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
060efb6ed72e25cf6839bedf22306311609bf135
18
12
2007-05-03T16:56:23Z
128.63.127.211
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
[[XDMF Model and Format]]
[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
dcceb770b05ac221f3c1c0341e58d53f47f093bc
19
18
2007-05-03T16:57:23Z
128.63.127.211
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
*[[XDMF Model and Format]]
*[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
fd423eb9bfdf8931dbc83bb6863233d2a56a66d5
20
19
2007-05-03T17:26:44Z
128.63.127.201
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 �attributes�, using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as �attributes� of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
*[[XDMF Model and Format]]
*[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
3a1504adde45eb801d32f5c386784ebd655b2b22
21
20
2007-05-03T17:27:35Z
128.63.127.201
0
wikitext
text/x-wiki
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
*[[XDMF Model and Format]]
*[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
142f32c6dac290e62924d81c498127f95f931970
27
21
2007-05-03T21:21:48Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
*[[XDMF Model and Format]]
*[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
025c9c88f49aeaa577661bbc2c286a96aa570c88
28
27
2007-05-03T21:28:31Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
*[[XDMF Model and Format]]
*[[XDMF API]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
2cead3b12bef67c7d613826caab9e7c88ae46688
36
28
2007-05-04T13:48:47Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
0d9355bb102818041568cab7b8bc2117b8a860fc
46
36
2008-05-02T15:54:28Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
6ebf48a44498ce36299efa7a27fb537ad5fbe46c
XDMF Model and Format
0
2
5
2007-05-03T14:11:51Z
128.63.127.201
0
New page: <p class=MsoNormal><b><span style='font-size:18.0pt;color:red'>XML</span></b></p> <p class=MsoNormal>The eXtensible Markup Language (XML) format is widely used for many purposes and is w...
wikitext
text/x-wiki
<p class=MsoNormal><b><span style='font-size:18.0pt;color:red'>XML</span></b></p>
<p class=MsoNormal>The eXtensible Markup Language (XML) format is widely used
for many purposes and is well documented at many sites. There are numerous open
source parsers available for XML. The XDMF API takes advantage of the libxml2
parser to provide the necessary functionality. Without going into too much
detail, XDMF views XML as a "personalized HTML" with some special
rules. It it case sensative and is made of three major components : elements,
entities, and processing information. In XDMF were primarily concerned with
the elements. These elements follow the basic form :</p>
<p class=MsoNormal style='margin-left:.5in'><span style='color:blue'><ElementTag</span></p>
<p class=MsoNormal style='margin-left:1.0in'><span style='color:blue'>AttributeName="AttribteValue"</span></p>
<p class=MsoNormal style='margin-left:1.0in'><span style='color:blue'>AttributeName="AttributeValue"</span></p>
<p class=MsoNormal style='margin-left:1.0in'><span style='color:blue'>
.. ></span></p>
<p class=MsoNormal style='margin-left:1.5in'><b><i><span style='color:blue'>CData</span></i></b></p>
<p class=MsoNormal style='margin-left:.5in'><span style='color:blue'></ElementTag></span></p>
<p class=MsoNormal>Each element begins with an <tag> and ends with a
</tag>. Optionally there can be several "Name=Value" pairs
which convey additional information. Between the <tag> and the
</tag> there can be other <tag></tag> pairs and/or character
data (CData). CData is typically where the values are stored; like the actual
text in an HTML document. The XML parser in the XDMF API parses the XML file
and builds an tree structure in memory to describe its contents. This tree can
be queried, modified, and then "serialized" back into XML.</p>
<p class=MsoNormal> </p>
<p class=MsoNormal>Comment in XML start with a <!-- and end with a
-->.� So <!--This is a Comment -->.</p>
<p class=MsoNormal> </p>
<p class=MsoNormal>XML is said to be well formed if it is syntactically
correct. This is all of the quotes match, all elements have end elements, etc.
XML is said to be valid if it conforms to the <i>Schema</i> or <i>DTD</i>
defined at the head of the document. For example, the schema might specify that
element type A can contain element B but not element C. Verifying that the
provided XML is well formed and/or valid are functions typically performed by
the XML parser. Additionally XDMF takes advantage of two major extensions to
XML :</p>
<p class=MsoNormal> </p>
<p class=MsoNormal><b>XInclude</b></p>
<p class=MsoNormal>As opposed to entity references in XML(which is a basic
substitution mechanism), XInclude allows for the inclusion of files that are
not well formed XML. This means that with XInclude the included file could be
well formed XML or perhaps a flat text file of values. The syntax looks like
this :</p>
<p class=MsoNormal> </p>
<p class=MsoNormal><b><span style='color:blue'><Xdmf Version="2.0"
xmlns:xi="</span></b><span style='color:blue'><a
href="http://www.w3.org/2001/XInclude"><b><span style='color:blue'>http://www.w3.org/2001/XInclude</span></b></a><b>"></b></span></p>
<p class=MsoNormal><b><span style='color:blue'><xi:include
href="Example3.xmf"/></span></b></p>
<p class=MsoNormal><b><span style='color:blue'></Xdmf></span></b></p>
<p class=MsoNormal> </p>
<p class=MsoNormal>the xmlns:xi establishes a namespace xi. Then anywhere
within the Xdmf element, xi:include will pull in the URL.</p>
<p class=MsoNormal> </p>
<p class=MsoNormal><b>XPath</b></p>
<p class=MsoNormal>This allows for elements in the XML document and the API to
reference specific elements in a document. For example :</p>
<p class=MsoNormal> </p>
<p class=MsoNormal>The first Grid in the first Domain</p>
<p class=MsoNormal><b><span style='color:blue'>/Xdmf/Domain/Grid</span></b></p>
<p class=MsoNormal>The tenth Grid .... XPath is one based.</p>
<p class=MsoNormal><b><span style='color:blue'>/Xdmf/Domain/Grid[10]</span></b></p>
<p class=MsoNormal>The first grid with an attribute <i>Name</i> which has a
value of <i>Copper Plate</i></p>
<p class=MsoNormal><b><span style='color:blue'>/Xdmf/Domain/Grid[@Name=Copper
Plate]</span></b></p>
<p class=MsoNormal> </p>
<p class=MsoNormal>All valid XDMF must appear between the <Xdmf> and the
</Xdmf>. So a minimal (empty) XDMF XML file would be :</p>
<p class=MsoNormal> </p>
<p class=MsoNormal><b><span style='color:blue'><?xml version="1.0"
?></span></b></p>
<p class=MsoNormal><b><span style='color:blue'><!DOCTYPE Xdmf SYSTEM
"Xdmf.dtd" []></span></b></p>
<p class=MsoNormal><b><span style='color:blue'><Xdmf Version=2.0></span></b></p>
<p class=MsoNormal><b><span style='color:blue'></Xdmf></span></b></p>
<p class=MsoNormal><b><span style='color:blue'> </span></b></p>
<p class=MsoNormal>While there exists an Xdmf DTD and a Schema they are only
necessary for validating parsers. For performance reasons, validation is
typically disabled.</p>
<p class=MsoNormal> </p>
<p class=MsoNormal><b><span style='font-size:18.0pt;color:red'>XDMF Elements</span></b></p>
<p class=MsoNormal> </p>
0d47bb2b19d3aab3bda4a3d1179303c24322a504
6
5
2007-05-03T14:29:07Z
128.63.127.201
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we\�re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
�.. >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid\[10\]'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid\[@Name="Copper Plate"\]'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" \[\]>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' � this is the default. A single array of values.
# '''Collection''' � a one dimension array of DataItems
# '''Tree''' � a hierarchical structure of DataItems
# '''HyperSlab''' � contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' � contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' � calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at \[0,0,0,0\], ending at \[50, 100, 150, 2\] that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem\[1\]" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 \* $1)">'''
''' <DataItem Reference="/Xdmf/DataItem\[1\]" />'''
''' <DataItem Reference="/Xdmf/DataItem\[2\]" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0\[5:15\]">'''
''' <DataItem Reference="/Xdmf/DataItem\[1\]" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem\[1\]" />'''
''' <DataItem Reference="/Xdmf/DataItem\[2\]" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem\[1\]" />'''
''' <DataItem Reference="/Xdmf/DataItem\[2\]" /> '''
''' <DataItem Reference="/Xdmf/DataItem\[3\]" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' � a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' � an array of Uniform grids
# '''Tree''' � a hierarchical group
# '''SubSet '''� a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid\[@Name="Main Grid"\]'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid\[@Name="Main Grid"\]'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex � a group of unconnected points
* Polyline � a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 � Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed � a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh � Axis are perpendicular
* 2DCoRectMesh � Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" \[\]>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" \[\]>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem\[@Name="Point Data"\]'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' � 9 values expected
* '''Tensor6''' � a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don\�t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
2a26feee31176feab7926403503f0327f603e543
7
6
2007-05-03T14:33:58Z
128.63.127.201
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>�</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
�.. >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' � this is the default. A single array of values.
# '''Collection''' � a one dimension array of DataItems
# '''Tree''' � a hierarchical structure of DataItems
# '''HyperSlab''' � contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' � contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' � calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' � a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' � an array of Uniform grids
# '''Tree''' � a hierarchical group
# '''SubSet '''� a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex � a group of unconnected points
* Polyline � a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 � Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed � a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh � Axis are perpendicular
* 2DCoRectMesh � Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' � 9 values expected
* '''Tensor6''' � a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
8ee08590daab349dfb749ca1fe22aae405436cc3
8
7
2007-05-03T15:09:26Z
128.63.127.201
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>�</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
�.. >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' � this is the default. A single array of values.
# '''Collection''' � a one dimension array of DataItems
# '''Tree''' � a hierarchical structure of DataItems
# '''HyperSlab''' � contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' � contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' � calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' � a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' � an array of Uniform grids
# '''Tree''' � a hierarchical group
# '''SubSet '''� a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex � a group of unconnected points
* Polyline � a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 � Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed � a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh � Axis are perpendicular
* 2DCoRectMesh � Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' � 9 values expected
* '''Tensor6''' � a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
1e3366ef206ac1e6217f7337a95bc3cf8be30c69
9
8
2007-05-03T16:05:26Z
128.63.127.211
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<br>
'''<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>'''
<br>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
1d015b5af8daf126379d8f3474eccaa90d58c558
10
9
2007-05-03T16:08:54Z
128.63.127.211
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<br>
'''<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>'''
<br>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
9ab5e308055d61d3f8cd053ffc33ca074f502f8e
16
10
2007-05-03T16:41:24Z
128.63.127.211
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology �.'''
'''<Geometry �'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
8d1a01340a14441cacdbd5d748179b6e21bff2cf
17
16
2007-05-03T16:50:07Z
128.63.127.211
0
wikitext
text/x-wiki
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
d0f6972305a28516c6bdbe4234a26f2eb5c8d9f8
29
17
2007-05-03T21:32:08Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
7f410f1cd7517cefec942016c4213b7bce1f0aca
30
29
2007-05-03T21:32:29Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
56d470a77e52ede8bbf457e96288915d28d606cf
32
30
2007-05-04T12:58:18Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element and Default XML Attributes'''
* Attribute
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain
Name (no default)
* Geometry
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information
Name (no default)
Value (no default)
* Xdmf
Version <span style='color:red'>2.0</span> | *
* Topology
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
bc63eb5dc0014536d85087b2fa598ee6b59c6f96
33
32
2007-05-04T13:01:48Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
8d066a55f0c9d5eeec23c8eca3dc82e809a5bf44
40
33
2007-05-24T15:18:52Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology Type="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
5287284d706215d1d110d8bbe62d6caefa1904db
41
40
2007-08-27T13:24:06Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
3cf7a4a7f54387bb99e220a28ee4c50f1c22166c
43
41
2008-02-01T14:43:47Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TypeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
3ade5e88ea6084d44e1b74e4a0950704a8d5d1b1
45
43
2008-05-01T16:05:57Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttribteValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concat two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TypeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
2ff5fe9a35b797b01930e81bf0f3519784ccab19
XDMF API
0
3
13
2007-05-03T16:11:57Z
128.63.127.201
0
New page: '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give a...
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>�</nowiki>MyXMLFile.xmf<nowiki>�</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki>�</nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet(<nowiki>�</nowiki>Domain<nowiki>�</nowiki>) <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement(<nowiki>�</nowiki>Grid<nowiki>�</nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath(<nowiki>�</nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki>�</nowiki>) <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, <nowiki>�</nowiki>Name<nowiki>�</nowiki>)
SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki>�</nowiki>Grid<nowiki>�</nowiki>)
Status = XdmfDOM.Set(SubGrid, <nowiki>�</nowiki>Name<nowiki>�</nowiki>, <nowiki>�</nowiki>My SubGrid<nowiki>�</nowiki>)
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write(<nowiki>�</nowiki>MyFile.xmf<nowiki>�</nowiki>)
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath(<nowiki>�</nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki>�</nowiki>)
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>�</nowiki>Name<nowiki>�</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, <nowiki>�</nowiki>Name<nowiki>�</nowiki>)
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set(<nowiki>�</nowiki>Name<nowiki>�</nowiki>, <nowiki>�</nowiki>My Grid<nowiki>�</nowiki>)
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import <nowiki>*</nowiki>
def Expression(<nowiki>*</nowiki>args) :
e = <nowiki>�</nowiki><nowiki>�</nowiki>
for arg in args :
if hasattr(arg, <nowiki>�</nowiki>GetTagName<nowiki>�</nowiki>) :
e += arg.GetTagName() + <nowiki>�</nowiki> <nowiki>�</nowiki>
else :
e += arg + <nowiki>�</nowiki> <nowiki>�</nowiki>
return XdmfExpr(e)
if __name__ == <nowiki>�</nowiki>__main__<nowiki>�</nowiki> :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print <nowiki>�</nowiki>a1 Values = <nowiki>�</nowiki>, a1.GetValues()
print <nowiki>�</nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki><nowiki>[</nowiki> 2:10 <nowiki>]</nowiki><nowiki>�</nowiki>).GetValues()
print <nowiki>�</nowiki>a2 Values = <nowiki>�</nowiki>, a2.GetValues()
print <nowiki>�</nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki><nowiki>[</nowiki><nowiki>�</nowiki>, a2, <nowiki>�</nowiki><nowiki>]</nowiki><nowiki>�</nowiki>).GetValues()
print <nowiki>�</nowiki>a1 + a2 = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> + <nowiki>�</nowiki>, a2).GetValues()
print <nowiki>�</nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> <nowiki>*</nowiki> <nowiki>�</nowiki>, a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print <nowiki>�</nowiki>a2 Values = <nowiki>�</nowiki>, a2.GetValues()
print <nowiki>�</nowiki>a1 , a2 (Interlace) = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> , <nowiki>�</nowiki>, a2).GetValues()
print <nowiki>�</nowiki>a1 , a2, a1 (Interlace) = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> , <nowiki>�</nowiki>, a2, <nowiki>�</nowiki> , <nowiki>�</nowiki>, a1).GetValues()
print <nowiki>�</nowiki>a1 ; a2 (Concat) = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> ; <nowiki>�</nowiki>, a2).GetValues()
print <nowiki>�</nowiki>where(a1 > 10) = <nowiki>�</nowiki> + Expression(<nowiki>�</nowiki>Where( <nowiki>�</nowiki>, a1 , <nowiki>�</nowiki> > 10)<nowiki>�</nowiki>).GetValues()
print <nowiki>�</nowiki>a2<nowiki>[</nowiki>where(a1 > 10)<nowiki>]</nowiki> = <nowiki>�</nowiki> + Expression(a2, <nowiki>�</nowiki><nowiki>[</nowiki>Where( <nowiki>�</nowiki>, a1 , <nowiki>�</nowiki> > 10)<nowiki>]</nowiki><nowiki>�</nowiki>).GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArray a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = <nowiki>�</nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75 ��
Connectivity = <nowiki>�</nowiki>3 2 5 1 �.
Values = <nowiki>�</nowiki>100 200 300 �..
<nowiki>#</nowiki> Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
<nowiki>#</nowiki> Open for Writing. This will truncate the file.
H5.Open(<nowiki>�</nowiki>Example1.h5:/Geometry<nowiki>�</nowiki>, <nowiki>�</nowiki>w<nowiki>�</nowiki>)
H5.Write(GeometryArray)
H5.Close()
<nowiki>#</nowiki> Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki>�</nowiki>Example1.h5:/Connectivity<nowiki>�</nowiki>, <nowiki>�</nowiki>rw<nowiki>�</nowiki>)
H5.Write(ConnectivityArray)
H5.Close()
<nowiki>#</nowiki> Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki>�</nowiki>Example1.h5:/Values<nowiki>�</nowiki>, <nowiki>�</nowiki>rw<nowiki>�</nowiki>)
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open(<nowiki>�</nowiki>Example1.h5:/Values<nowiki>�</nowiki>, <nowiki>�</nowiki>rw<nowiki>�</nowiki>)
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse(<nowiki>�</nowiki>Points.xmf<nowiki>�</nowiki>)
ge = dom.FindElementByPath(<nowiki>�</nowiki>/Xdmf/Domain/Grid<nowiki>�</nowiki>)
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print <nowiki>�</nowiki>Values = <nowiki>�</nowiki>, conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print <nowiki>�</nowiki>Geo Type = <nowiki>�</nowiki>, geo.GetGeometryTypeAsString(), <nowiki>�</nowiki> <nowiki>#</nowiki> Points = <nowiki>�</nowiki>, geo.GetNumberOfPoints()
print <nowiki>�</nowiki>Points = <nowiki>�</nowiki>, points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api can get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can
root.Build()
<nowiki>#</nowiki> Information
i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure
<nowiki>#</nowiki> Insert() creates an XML node and inserts it under
<nowiki>#</nowiki> the parent
<nowiki>#</nowiki> Domain
dm = XdmfDomain()
root.Insert(dm)
<nowiki>#</nowiki> Grid
g = XdmfGrid()
g.SetName("Structured Grid")
<nowiki>#</nowiki> Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString(<nowiki>�</nowiki>10 20 30<nowiki>�</nowiki>)
<nowiki>#</nowiki> Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
<nowiki>#</nowiki> Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
<nowiki>#</nowiki> Update XML and Write Values to DataItems
root.Build() <nowiki>#</nowiki> DataItems > 100 values are heavy
print d.Serialize() <nowiki>#</nowiki> prints to stdout
d.Write(<nowiki>�</nowiki>MyMesh.xmf<nowiki>�</nowiki>) <nowiki>#</nowiki> write to file
e3eb8b2abdfe77d1a53e0bbd58d6c7edad8eb6cd
14
13
2007-05-03T16:30:38Z
128.63.127.201
0
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki></nowiki>MyXMLFile.xmf<nowiki></nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>)
Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>)
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>)
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>)
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as
input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import <nowiki>*</nowiki>
def Expression(<nowiki>*</nowiki>args) :
e = <nowiki></nowiki><nowiki></nowiki>
for arg in args :
if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) :
e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki>
else :
e += arg + <nowiki></nowiki> <nowiki></nowiki>
return XdmfExpr(e)
if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues()
print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues()
print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no
wiki>).GetValues()
print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues()
print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>where(a1 > 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> > 10)<nowiki></nowiki>).GetValues()
print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 > 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> > 10
)<nowiki>]</nowiki><nowiki></nowiki>).GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = <nowiki></nowiki>3 2 5 1 .
Values = <nowiki></nowiki>100 200 300 ..
<nowiki>#</nowiki> Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
<nowiki>#</nowiki> Open for Writing. This will truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>)
H5.Write(GeometryArray)
H5.Close()
<nowiki>#</nowiki> Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ConnectivityArray)
H5.Close()
<nowiki>#</nowiki> Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>)
ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>)
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints()
print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec
ursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can
root.Build()
<nowiki>#</nowiki> Information
i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure
<nowiki>#</nowiki> Insert() creates an XML node and inserts it under
<nowiki>#</nowiki> the parent
<nowiki>#</nowiki> Domain
dm = XdmfDomain()
root.Insert(dm)
<nowiki>#</nowiki> Grid
g = XdmfGrid()
g.SetName("Structured Grid")
<nowiki>#</nowiki> Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>)
<nowiki>#</nowiki> Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
<nowiki>#</nowiki> Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
<nowiki>#</nowiki> Update XML and Write Values to DataItems
root.Build() <nowiki>#</nowiki> DataItems > 100 values are heavy
print d.Serialize() <nowiki>#</nowiki> prints to stdout
d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file
6f1614df052fb3ca7b7c6991107e6e6ba33a8e82
15
14
2007-05-03T16:31:41Z
128.63.127.201
0
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki></nowiki>MyXMLFile.xmf<nowiki></nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>)
Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>)
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>)
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>)
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as
input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import <nowiki>*</nowiki>
def Expression(<nowiki>*</nowiki>args) :
e = <nowiki></nowiki><nowiki></nowiki>
for arg in args :
if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) :
e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki>
else :
e += arg + <nowiki></nowiki> <nowiki></nowiki>
return XdmfExpr(e)
if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues()
print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues()
print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no
wiki>).GetValues()
print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues()
print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>where(a1 > 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> > 10)<nowiki></nowiki>).GetValues()
print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 > 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> > 10
)<nowiki>]</nowiki><nowiki></nowiki>).GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = <nowiki></nowiki>3 2 5 1 .
Values = <nowiki></nowiki>100 200 300 ..
<nowiki>#</nowiki> Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
<nowiki>#</nowiki> Open for Writing. This will truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>)
H5.Write(GeometryArray)
H5.Close()
<nowiki>#</nowiki> Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ConnectivityArray)
H5.Close()
<nowiki>#</nowiki> Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>)
ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>)
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints()
print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec
ursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can
root.Build()
<nowiki>#</nowiki> Information
i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure
<nowiki>#</nowiki> Insert() creates an XML node and inserts it under
<nowiki>#</nowiki> the parent
<nowiki>#</nowiki> Domain
dm = XdmfDomain()
root.Insert(dm)
<nowiki>#</nowiki> Grid
g = XdmfGrid()
g.SetName("Structured Grid")
<nowiki>#</nowiki> Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>)
<nowiki>#</nowiki> Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
<nowiki>#</nowiki> Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() <nowiki>#</nowiki> DataItems > 100 values are heavy
print d.Serialize() <nowiki>#</nowiki> prints to stdout
d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file
eeca8af04dcfd9bbb81ec300d04e251969008f43
22
15
2007-05-03T17:35:04Z
128.63.127.211
0
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>)
Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>)
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>)
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>)
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>)
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>)
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as
input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import <nowiki>*</nowiki>
def Expression(<nowiki>*</nowiki>args) :
e = <nowiki></nowiki><nowiki></nowiki>
for arg in args :
if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) :
e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki>
else :
e += arg + <nowiki></nowiki> <nowiki></nowiki>
return XdmfExpr(e)
if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues()
print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues()
print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no
wiki>).GetValues()
print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues()
print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues()
print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues()
print <nowiki></nowiki>where(a1 > 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> > 10)<nowiki></nowiki>).GetValues()
print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 > 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> > 10
)<nowiki>]</nowiki><nowiki></nowiki>).GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = <nowiki></nowiki>3 2 5 1 .
Values = <nowiki></nowiki>100 200 300 ..
<nowiki>#</nowiki> Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
<nowiki>#</nowiki> Open for Writing. This will truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>)
H5.Write(GeometryArray)
H5.Close()
<nowiki>#</nowiki> Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ConnectivityArray)
H5.Close()
<nowiki>#</nowiki> Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
<nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file.
H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>)
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>)
ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>)
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints()
print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec
ursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can
root.Build()
<nowiki>#</nowiki> Information
i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure
<nowiki>#</nowiki> Insert() creates an XML node and inserts it under
<nowiki>#</nowiki> the parent
<nowiki>#</nowiki> Domain
dm = XdmfDomain()
root.Insert(dm)
<nowiki>#</nowiki> Grid
g = XdmfGrid()
g.SetName("Structured Grid")
<nowiki>#</nowiki> Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>)
<nowiki>#</nowiki> Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
<nowiki>#</nowiki> Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() <nowiki>#</nowiki> DataItems > 100 values are heavy
print d.Serialize() <nowiki>#</nowiki> prints to stdout
d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file
083d1bddeaeadfba5d7e641f098b7eb95d34214a
23
22
2007-05-03T17:55:49Z
128.63.127.211
0
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Values
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
d3ea8f823282597dfea7fb55686cd76630fae3e9
24
23
2007-05-03T18:06:56Z
Jerry
2
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
535cb1be8240b1e6affd9a29307a49f56251d182
31
24
2007-05-03T21:33:07Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the
se functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod
el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parser strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel
ow a parent node :
XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
c4c16d1f7956f8e7415942a799c80eff6eadf373
42
31
2007-12-11T15:39:11Z
Dave.demarle
5
fix typos
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
061c418d8fb4fa80c594b4c01721814e91b86a5c
44
42
2008-02-01T15:04:03Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
931a0839a748265cdf910d113e4825a96a2f3343
File:XdmfLogo.gif
6
4
25
2007-05-03T21:16:32Z
Jerry
2
Try a Logo
wikitext
text/x-wiki
Try a Logo
a35ab1b3e3d2e8a45a7e7ebf6009b93a1fe6fae3
File:XdmfLogo1.gif
6
5
26
2007-05-03T21:20:54Z
Jerry
2
Smaller Logo
wikitext
text/x-wiki
Smaller Logo
17e4dd8f7ee44fae32a05b32f213c8b2b55e11b8
Get Xdmf original
0
6
34
2007-05-04T13:32:31Z
Jerry
2
New page: == '''Obtaining and Installing XDMF''' == The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, ...
wikitext
text/x-wiki
== '''Obtaining and Installing XDMF''' ==
The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin.
CVS Access to the XDMF Source Code Repository
XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS.
Anonymous User Read-Only Access
You can obtain read-only access to the CVS repository as follows.
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login
(respond with password xdmf)
Follow this command by checking out the source code:
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf
This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool.
'''Installation'''
XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com].
Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf (./configure �prefix �) method with CMake.
Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version :
# mkdir MyXdmf
# cd MyXdmf
# cvs <nowiki>-d ...</nowiki> login
# cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code
# mkdir Linux
# cd Linux
# cmake ../Xdmf
CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake.
In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options.
Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files :
* libXdmf.[a so dll] C++ class library for XDMF
* _Xdmf.[so dll] Python interface
* libXdmfTCL.[so dll] Tcl interface
* XdmfFormatExample Executable to write/read XDMF file
The Python interface has been built with the �shadow classes�. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in �/Xdmf/python) somewhere in your Python path.
dfad60182082cf30233da703db09b59a3732b49c
35
34
2007-05-04T13:48:00Z
Jerry
2
wikitext
text/x-wiki
== '''Obtaining and Installing XDMF''' ==
The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin.
CVS Access to the XDMF Source Code Repository
XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS.
Anonymous User Read-Only Access
You can obtain read-only access to the CVS repository as follows.
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login
(respond with password xdmf)
Follow this command by checking out the source code:
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf
This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool.
'''Installation'''
XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com].
Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf <nowiki>(./configure --prefix...)</nowiki> method with CMake.
Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version :
# mkdir MyXdmf
# cd MyXdmf
# cvs <nowiki>-d ...</nowiki> login
# cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code
# mkdir Linux
# cd Linux
# cmake ../Xdmf
CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake.
In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options.
Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files :
* libXdmf.[a so dll] C++ class library for XDMF
* _Xdmf.[so dll] Python interface
* libXdmfTCL.[so dll] Tcl interface
* XdmfFormatExample Executable to write/read XDMF file
The Python interface has been built with the shadow classes. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in <nowiki>.../Xdmf/libsrc/Xdmf.py</nowiki>) somewhere in your Python path.
1f7090badf41e85866502c62d76aa63a72888040
File:TwoHex.jpg
6
7
37
2007-05-04T14:41:35Z
Jerry
2
Two Hexahedron from ParaView
wikitext
text/x-wiki
Two Hexahedron from ParaView
fa19c3f070231906fb2aa9b7971a44277b72260d
Read Xdmf
0
8
38
2007-05-04T15:35:45Z
Jerry
2
New page: == Reading XDMF Data == [[Image:TwoHex.jpg]] The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face. There are values centered a...
wikitext
text/x-wiki
== Reading XDMF Data ==
[[Image:TwoHex.jpg]]
The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face.
There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are
all stored directly in the XML file.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf>
<Domain>
<Grid Name="TestGrid">
<Topology Type="Hexahedron" NumberOfElements="2" >
<DataItem Format="XML" DataType="Float"
Dimensions="2 8">
0 1 7 6 3 4 10 9
1 2 8 7 4 5 11 10
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3 3">
0.0 0.0 1.0
1.0 0.0 1.0
3.0 0.0 2.0
0.0 1.0 1.0
1.0 1.0 1.0
3.0 2.0 2.0
0.0 0.0 -1.0
1.0 0.0 -1.0
3.0 0.0 -2.0
0.0 1.0 -1.0
1.0 1.0 -1.0
3.0 2.0 -2.0
</DataItem>
</Geometry>
<Attribute Name="NodeValues" Center="Node">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3" >
100 200 300
300 400 500
300 400 500
500 600 700
</DataItem>
</Attribute>
<Attribute Name="CellValues" Center="Cell">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="2" >
100 200
</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and
retrieving the data values.
from Xdmf import *
dom = XdmfDOM()
dom.Parse('MyGrid.xmf')
# We now have a tree. Find the one and only Grid element
ge = dom.FindElementByPath('/Xdmf/Domain/Grid')
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
# Read Light Data
grid.UpdateInformation()
# Read Heavy Data which includes Topology and Geometry
grid.Update()
top = grid.GetTopology()
conn = top.GetConnectivity()
print 'Values = ', conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print 'Geo Type = ', geo.GetGeometryTypeAsString(), ' # Points = ', geo.GetNumberOfPoints()
print 'Points = ', points.GetValues()
# for each Attribute, print Light Data and Values
for i in range(grid.GetNumberOfAttributes()) :
attr = grid.GetAttribute(i)
print 'Attribute ', i, ' Name = ', attr.Get('Name')
# Attribute HeavyData is not Updated by default
# there could potentially be many causing huge IO
attr.Update()
vals = attr.GetValues()
print 'Values ', vals.GetValues()
98255db3b4b8800f785d362434a2cb0580fa134c
Write Xdmf
0
9
39
2007-05-04T16:17:53Z
Jerry
2
New page: == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provi...
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="Time" Value="0.0123"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
~
fccd8c7391a9bf679fcb48bdc9105c277b5864a7
49
39
2008-05-02T19:36:20Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
~
69cb45c583aee33a5a93361b2ba0a5b1bbed6eac
Write from Fortran
0
10
47
2008-05-02T16:32:03Z
Jerry
2
New page: == Writing Xdmf from Fortran == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, h...
wikitext
text/x-wiki
== Writing Xdmf from Fortran ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider
the following Fortran program which build a grid of Hexahedra with some node and cell centered values :
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Grid of Hexahedron Centered at 0,0,0
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN )
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
INTEGER I, J, K, IDX
REAL*8 X, Y, Z, DX, DY, DZ
C Print *, 'Size = ', IDIM, JDIM, KDIM
PRINT *, 'Initialze Problem'
C XYZ Values of Nodes
C From -1 to 1
DX = 2.0 / ( IDIM - 1 )
DY = 2.0 / ( JDIM - 1 )
DZ = 2.0 / ( KDIM - 1 )
Z = -1.0
DO 112 K= 1, KDIM
Y = -1.0
DO 111 J= 1, JDIM
X = -1.0
DO 110 I= 1, IDIM
XYZ( 1, I, J, K ) = X
XYZ( 2, I, J, K ) = Y
XYZ( 3, I, J, K ) = Z
X = X + DX
110 CONTINUE
Y = Y + DY
111 CONTINUE
Z = Z + DZ
112 CONTINUE
C Connections
IDX = 1
DO 122 K= 0, KDIM - 2
DO 121 J= 0, JDIM - 2
DO 120 I= 1, IDIM - 1
ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I
ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I
IDX = IDX + 1
120 CONTINUE
121 CONTINUE
122 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Node Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
INTEGER I, J, K
REAL*8 X, Y, Z
PRINT *, 'Calculating Node Centered Data'
DO 212, K=1, KDIM
DO 211, J=1, JDIM
DO 210, I=1, IDIM
X = XYZ( 1, I, J, K )
Y = XYZ( 2, I, J, K )
Z = XYZ( 3, I, J, K )
NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z ))
210 CONTINUE
211 CONTINUE
212 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Cell Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
INTEGER IDIM, JDIM, KDIM, ITER, KICKER
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
INTEGER I, J, K
PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER
DO 312, K=1, KDIM - 1
DO 311, J=1, JDIM - 1
DO 310, I=1, IDIM - 1
X = XYZ( 1, I, J, K )
CCVALUES( I, J, K ) =
C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) /
C EXP( X / ( 1.0 * ITER ) )
310 CONTINUE
311 CONTINUE
312 CONTINUE
C Waste Time
DO 313 I=1, 1000000
X = 0.1 * ITER / I
Y = SQRT( X * X )
Z = EXP( Y )
313 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Main Program :
C Initialize Grid
C Initialize Node Centered Data
C For Iteration = 1 to 10
C Generate Cell Centered Data
C Done
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
PROGRAM HexMesh
PARAMETER ( IDIM = 11 )
PARAMETER ( JDIM = 13 )
PARAMETER ( KDIM = 15 )
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
C
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
C
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
C
INTEGER ITER, KICKER, NITER, NARG
INTEGER IUNIT
CHARACTER*80 ARGIN
C
NARG = IARGC()
IF( NARG .GE. 1 ) THEN
CALL GETARG( 1, ARGIN )
READ( ARGIN, '(I)') NITER
ELSE
NITER = 10
ENDIF
CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN )
CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
C
IUNIT = 14
OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) IDIM * JDIM * KDIM
WRITE ( IUNIT, * ) XYZ
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
WRITE ( IUNIT, * ) ICONN
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) NCVALUES
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' )
REWIND IUNIT
C
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now
let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML
via print statements (we could also shove bamboo shoots under our fingernails). A better approach
would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary
Xdmf calls to produce valid Xdmf XML and HDF5 files :
#include <Xdmf.h>
// We want the filenames to be based on the iteration
// and padded with zeros
using std::setw;
using std::setfill;
// This works with g77. Different compilers require different
// name mangling.
'''#define XdmfWrite xdmfwrite_'''
//
// C/C++ expect NULL terminated strings. Here is a conversion subroutine.
char *
DemoConvertFortranString( char *FtnName ) {
static char Name[80];
char *np;
memcpy(Name, FtnName, 79 );
Name[79] = '\0';
np = &Name[78];
while( ( np > Name ) && ( *np <= ' ') ) {
np--;
}
*np = '\0';
return( Name );
}
//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {
//
void
'''XdmfWrite(''' char *FtnName, int *Iteration,
int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points,
XdmfInt32 *Conns, XdmfFloat64 *NodeData,
XdmfFloat64 *CellData){
char *Name;
char FullName[80];
ostrstream DataName(FullName, 80);
XdmfDOM dom;
XdmfRoot root;
XdmfDomain domain;
XdmfGrid grid;
XdmfTime time;
XdmfTopology *topology;
XdmfGeometry *geometry;
XdmfAttribute nodedata;
XdmfAttribute celldata;
XdmfArray *array;
//
Name = DemoConvertFortranString( FtnName );
//
root.SetDOM(&dom);
root.SetVersion(2.0);
root.Build();
// Domain
root.Insert(&domain);
// Grid
grid.SetName("Demonstration Grid");
domain.Insert(&grid);
time.SetTimeType(XDMF_TIME_SINGLE);
time.SetValue(0.001 * *Iteration);
grid.Insert(&time);
// Topology
topology = grid.GetTopology();
topology->SetTopologyType(XDMF_HEX);
topology->SetNumberOfElements(*NumberOfHex);
// Fortran is 1 based while c++ is 0 based so
// Either subtract 1 from all connections or specify a BaseOffset
topology->SetBaseOffset(1);
// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
array = topology->GetConnectivity();
array->SetNumberOfElements(*NumberOfHex * 8);
array->SetValues(0, Conns, *NumberOfHex * 8);
// C++ string hocus pocus.
// We're actually building the string in FullName[] but were using streams.
// the DatasetName will be Demo_00001.h5:/Conns.
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends;
// Where the data will actually be written
array->SetHeavyDataSetName(FullName);
// Geometry
geometry = grid.GetGeometry();
geometry->SetGeometryType(XDMF_GEOMETRY_XYZ);
geometry->SetNumberOfPoints(*NumberOfPoints);
array = geometry->GetPoints();
array->SetValues(0, Points, *NumberOfPoints * 3);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends;
array->SetHeavyDataSetName(FullName);
// Node Data
nodedata.SetName("Node Scalar");
nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = nodedata.GetValues();
array->SetNumberOfElements(*NumberOfPoints);
array->SetValues(0, NodeData, *NumberOfPoints);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends;
array->SetHeavyDataSetName(FullName);
// Cell Data
celldata.SetName("Cell Scalar");
celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = celldata.GetValues();
array->SetNumberOfElements(*NumberOfHex);
array->SetValues(0, CellData, *NumberOfHex);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends;
array->SetHeavyDataSetName(FullName);
// Attach and Write
grid.Insert(&nodedata);
grid.Insert(&celldata);
// Build is recursive ... it will be called on all of the child nodes.
// This updates the DOM and writes the HDF5
root.Build();
// Write the XML
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends;
dom.Write(FullName);
}
}
Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()'''
Original :
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Modified :
INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
INPNT = IDIM * JDIM * KDIM
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
'''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)'''
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Now the program produces one HDF5 file and one XML file for each iteration. The final step would be to group
all of these together so we could animate them over time. Instead of duplicating the XML in another file for
each grid, we can use a little XML magic to pull them together :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0">
<Domain>
<Grid GridType="Collection" CollectionType="Temporal">
<xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
</Grid>
</Domain>
</Xdmf>
This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists
of the first (in our case, the only) grid in each file.
1f513ba184c9707c9787ab2640fd0d4716ff432c
48
47
2008-05-02T16:35:05Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf from Fortran ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider
the following Fortran program which build a grid of Hexahedra with some node and cell centered values :
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Grid of Hexahedron Centered at 0,0,0
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN )
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
INTEGER I, J, K, IDX
REAL*8 X, Y, Z, DX, DY, DZ
C Print *, 'Size = ', IDIM, JDIM, KDIM
PRINT *, 'Initialze Problem'
C XYZ Values of Nodes
C From -1 to 1
DX = 2.0 / ( IDIM - 1 )
DY = 2.0 / ( JDIM - 1 )
DZ = 2.0 / ( KDIM - 1 )
Z = -1.0
DO 112 K= 1, KDIM
Y = -1.0
DO 111 J= 1, JDIM
X = -1.0
DO 110 I= 1, IDIM
XYZ( 1, I, J, K ) = X
XYZ( 2, I, J, K ) = Y
XYZ( 3, I, J, K ) = Z
X = X + DX
110 CONTINUE
Y = Y + DY
111 CONTINUE
Z = Z + DZ
112 CONTINUE
C Connections
IDX = 1
DO 122 K= 0, KDIM - 2
DO 121 J= 0, JDIM - 2
DO 120 I= 1, IDIM - 1
ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I
ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I
IDX = IDX + 1
120 CONTINUE
121 CONTINUE
122 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Node Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
INTEGER I, J, K
REAL*8 X, Y, Z
PRINT *, 'Calculating Node Centered Data'
DO 212, K=1, KDIM
DO 211, J=1, JDIM
DO 210, I=1, IDIM
X = XYZ( 1, I, J, K )
Y = XYZ( 2, I, J, K )
Z = XYZ( 3, I, J, K )
NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z ))
210 CONTINUE
211 CONTINUE
212 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Cell Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
INTEGER IDIM, JDIM, KDIM, ITER, KICKER
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
INTEGER I, J, K
PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER
DO 312, K=1, KDIM - 1
DO 311, J=1, JDIM - 1
DO 310, I=1, IDIM - 1
X = XYZ( 1, I, J, K )
CCVALUES( I, J, K ) =
C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) /
C EXP( X / ( 1.0 * ITER ) )
310 CONTINUE
311 CONTINUE
312 CONTINUE
C Waste Time
DO 313 I=1, 1000000
X = 0.1 * ITER / I
Y = SQRT( X * X )
Z = EXP( Y )
313 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Main Program :
C Initialize Grid
C Initialize Node Centered Data
C For Iteration = 1 to 10
C Generate Cell Centered Data
C Done
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
PROGRAM HexMesh
PARAMETER ( IDIM = 11 )
PARAMETER ( JDIM = 13 )
PARAMETER ( KDIM = 15 )
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
C
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
C
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
C
INTEGER ITER, KICKER, NITER, NARG
INTEGER IUNIT
CHARACTER*80 ARGIN
C
NARG = IARGC()
IF( NARG .GE. 1 ) THEN
CALL GETARG( 1, ARGIN )
READ( ARGIN, '(I)') NITER
ELSE
NITER = 10
ENDIF
CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN )
CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
C
IUNIT = 14
OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) IDIM * JDIM * KDIM
WRITE ( IUNIT, * ) XYZ
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
WRITE ( IUNIT, * ) ICONN
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) NCVALUES
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' )
REWIND IUNIT
C
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now
let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML
via print statements (we could also shove bamboo shoots under our fingernails). A better approach
would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary
Xdmf calls to produce valid Xdmf XML and HDF5 files :
#include <Xdmf.h>
// We want the filenames to be based on the iteration
// and padded with zeros
using std::setw;
using std::setfill;
// This works with g77. Different compilers require different
// name mangling.
'''#define XdmfWrite xdmfwrite_'''
//
// C/C++ expect NULL terminated strings. Here is a conversion subroutine.
char *
DemoConvertFortranString( char *FtnName ) {
static char Name[80];
char *np;
memcpy(Name, FtnName, 79 );
Name[79] = '\0';
np = &Name[78];
while( ( np > Name ) && ( *np <= ' ') ) {
np--;
}
*np = '\0';
return( Name );
}
//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {
//
void
'''XdmfWrite(''' char *FtnName, int *Iteration,
int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points,
XdmfInt32 *Conns, XdmfFloat64 *NodeData,
XdmfFloat64 *CellData){
char *Name;
char FullName[80];
ostrstream DataName(FullName, 80);
XdmfDOM dom;
XdmfRoot root;
XdmfDomain domain;
XdmfGrid grid;
XdmfTime time;
XdmfTopology *topology;
XdmfGeometry *geometry;
XdmfAttribute nodedata;
XdmfAttribute celldata;
XdmfArray *array;
//
Name = DemoConvertFortranString( FtnName );
//
root.SetDOM(&dom);
root.SetVersion(2.0);
root.Build();
// Domain
root.Insert(&domain);
// Grid
grid.SetName("Demonstration Grid");
domain.Insert(&grid);
time.SetTimeType(XDMF_TIME_SINGLE);
time.SetValue(0.001 * *Iteration);
grid.Insert(&time);
// Topology
topology = grid.GetTopology();
topology->SetTopologyType(XDMF_HEX);
topology->SetNumberOfElements(*NumberOfHex);
// Fortran is 1 based while c++ is 0 based so
// Either subtract 1 from all connections or specify a BaseOffset
topology->SetBaseOffset(1);
// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
array = topology->GetConnectivity();
array->SetNumberOfElements(*NumberOfHex * 8);
array->SetValues(0, Conns, *NumberOfHex * 8);
// C++ string hocus pocus.
// We're actually building the string in FullName[] but were using streams.
// the DatasetName will be Demo_00001.h5:/Conns.
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends;
// Where the data will actually be written
array->SetHeavyDataSetName(FullName);
// Geometry
geometry = grid.GetGeometry();
geometry->SetGeometryType(XDMF_GEOMETRY_XYZ);
geometry->SetNumberOfPoints(*NumberOfPoints);
array = geometry->GetPoints();
array->SetValues(0, Points, *NumberOfPoints * 3);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends;
array->SetHeavyDataSetName(FullName);
// Node Data
nodedata.SetName("Node Scalar");
nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = nodedata.GetValues();
array->SetNumberOfElements(*NumberOfPoints);
array->SetValues(0, NodeData, *NumberOfPoints);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends;
array->SetHeavyDataSetName(FullName);
// Cell Data
celldata.SetName("Cell Scalar");
celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = celldata.GetValues();
array->SetNumberOfElements(*NumberOfHex);
array->SetValues(0, CellData, *NumberOfHex);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends;
array->SetHeavyDataSetName(FullName);
// Attach and Write
grid.Insert(&nodedata);
grid.Insert(&celldata);
// Build is recursive ... it will be called on all of the child nodes.
// This updates the DOM and writes the HDF5
root.Build();
// Write the XML
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends;
dom.Write(FullName);
}
}
Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()'''
Original :
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Modified :
INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
INPNT = IDIM * JDIM * KDIM
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
'''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)'''
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Now the program produces one HDF5 file and one XML file for each iteration. The final step would be to group
all of these together so we could animate them over time. Instead of duplicating the XML in another file for
each grid, we can use a little XML magic to pull them together :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0">
<Domain>
<Grid GridType="Collection" CollectionType="Temporal">
<xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
</Grid>
</Domain>
</Xdmf>
This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists
of the first (in our case, the only) grid in each file. This XML file could be generated programmtically
or by a post processing script.
a196dc78fada2864eff2feeea49e334784c09df8
50
48
2008-05-02T19:45:47Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf from Fortran ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider
the following Fortran program which build a grid of Hexahedra with some node and cell centered values :
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Grid of Hexahedron Centered at 0,0,0
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN )
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
INTEGER I, J, K, IDX
REAL*8 X, Y, Z, DX, DY, DZ
C Print *, 'Size = ', IDIM, JDIM, KDIM
PRINT *, 'Initialze Problem'
C XYZ Values of Nodes
C From -1 to 1
DX = 2.0 / ( IDIM - 1 )
DY = 2.0 / ( JDIM - 1 )
DZ = 2.0 / ( KDIM - 1 )
Z = -1.0
DO 112 K= 1, KDIM
Y = -1.0
DO 111 J= 1, JDIM
X = -1.0
DO 110 I= 1, IDIM
XYZ( 1, I, J, K ) = X
XYZ( 2, I, J, K ) = Y
XYZ( 3, I, J, K ) = Z
X = X + DX
110 CONTINUE
Y = Y + DY
111 CONTINUE
Z = Z + DZ
112 CONTINUE
C Connections
IDX = 1
DO 122 K= 0, KDIM - 2
DO 121 J= 0, JDIM - 2
DO 120 I= 1, IDIM - 1
ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I
ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I
IDX = IDX + 1
120 CONTINUE
121 CONTINUE
122 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Node Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
INTEGER I, J, K
REAL*8 X, Y, Z
PRINT *, 'Calculating Node Centered Data'
DO 212, K=1, KDIM
DO 211, J=1, JDIM
DO 210, I=1, IDIM
X = XYZ( 1, I, J, K )
Y = XYZ( 2, I, J, K )
Z = XYZ( 3, I, J, K )
NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z ))
210 CONTINUE
211 CONTINUE
212 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Cell Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
INTEGER IDIM, JDIM, KDIM, ITER, KICKER
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
INTEGER I, J, K
PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER
DO 312, K=1, KDIM - 1
DO 311, J=1, JDIM - 1
DO 310, I=1, IDIM - 1
X = XYZ( 1, I, J, K )
CCVALUES( I, J, K ) =
C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) /
C EXP( X / ( 1.0 * ITER ) )
310 CONTINUE
311 CONTINUE
312 CONTINUE
C Waste Time
DO 313 I=1, 1000000
X = 0.1 * ITER / I
Y = SQRT( X * X )
Z = EXP( Y )
313 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Main Program :
C Initialize Grid
C Initialize Node Centered Data
C For Iteration = 1 to 10
C Generate Cell Centered Data
C Done
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
PROGRAM HexMesh
PARAMETER ( IDIM = 11 )
PARAMETER ( JDIM = 13 )
PARAMETER ( KDIM = 15 )
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
C
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
C
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
C
INTEGER ITER, KICKER, NITER, NARG
INTEGER IUNIT
CHARACTER*80 ARGIN
C
NARG = IARGC()
IF( NARG .GE. 1 ) THEN
CALL GETARG( 1, ARGIN )
READ( ARGIN, '(I)') NITER
ELSE
NITER = 10
ENDIF
CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN )
CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
C
IUNIT = 14
OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) IDIM * JDIM * KDIM
WRITE ( IUNIT, * ) XYZ
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
WRITE ( IUNIT, * ) ICONN
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) NCVALUES
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' )
REWIND IUNIT
C
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now
let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML
via print statements (we could also shove bamboo shoots under our fingernails). A better approach
would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary
Xdmf calls to produce valid Xdmf XML and HDF5 files :
#include <Xdmf.h>
// We want the filenames to be based on the iteration
// and padded with zeros
using std::setw;
using std::setfill;
// This works with g77. Different compilers require different
// name mangling.
'''#define XdmfWrite xdmfwrite_'''
//
// C/C++ expect NULL terminated strings. Here is a conversion subroutine.
char *
DemoConvertFortranString( char *FtnName ) {
static char Name[80];
char *np;
memcpy(Name, FtnName, 79 );
Name[79] = '\0';
np = &Name[78];
while( ( np > Name ) && ( *np <= ' ') ) {
np--;
}
*np = '\0';
return( Name );
}
//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {
//
void
'''XdmfWrite(''' char *FtnName, int *Iteration,
int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points,
XdmfInt32 *Conns, XdmfFloat64 *NodeData,
XdmfFloat64 *CellData){
char *Name;
char FullName[80];
ostrstream DataName(FullName, 80);
XdmfDOM dom;
XdmfRoot root;
XdmfDomain domain;
XdmfGrid grid;
XdmfTime time;
XdmfTopology *topology;
XdmfGeometry *geometry;
XdmfAttribute nodedata;
XdmfAttribute celldata;
XdmfArray *array;
//
Name = DemoConvertFortranString( FtnName );
//
root.SetDOM(&dom);
root.SetVersion(2.0);
root.Build();
// Domain
root.Insert(&domain);
// Grid
grid.SetName("Demonstration Grid");
domain.Insert(&grid);
time.SetTimeType(XDMF_TIME_SINGLE);
time.SetValue(0.001 * *Iteration);
grid.Insert(&time);
// Topology
topology = grid.GetTopology();
topology->SetTopologyType(XDMF_HEX);
topology->SetNumberOfElements(*NumberOfHex);
// Fortran is 1 based while c++ is 0 based so
// Either subtract 1 from all connections or specify a BaseOffset
topology->SetBaseOffset(1);
// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
array = topology->GetConnectivity();
array->SetNumberOfElements(*NumberOfHex * 8);
array->SetValues(0, Conns, *NumberOfHex * 8);
// C++ string hocus pocus.
// We're actually building the string in FullName[] but were using streams.
// the DatasetName will be Demo_00001.h5:/Conns.
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends;
// Where the data will actually be written
array->SetHeavyDataSetName(FullName);
// Geometry
geometry = grid.GetGeometry();
geometry->SetGeometryType(XDMF_GEOMETRY_XYZ);
geometry->SetNumberOfPoints(*NumberOfPoints);
array = geometry->GetPoints();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetValues(0, Points, *NumberOfPoints * 3);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends;
array->SetHeavyDataSetName(FullName);
// Node Data
nodedata.SetName("Node Scalar");
nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = nodedata.GetValues();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetNumberOfElements(*NumberOfPoints);
array->SetValues(0, NodeData, *NumberOfPoints);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends;
array->SetHeavyDataSetName(FullName);
// Cell Data
celldata.SetName("Cell Scalar");
celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = celldata.GetValues();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetNumberOfElements(*NumberOfHex);
array->SetValues(0, CellData, *NumberOfHex);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends;
array->SetHeavyDataSetName(FullName);
// Attach and Write
grid.Insert(&nodedata);
grid.Insert(&celldata);
// Build is recursive ... it will be called on all of the child nodes.
// This updates the DOM and writes the HDF5
root.Build();
// Write the XML
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends;
dom.Write(FullName);
}
}
Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()'''
Original :
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Modified :
INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
INPNT = IDIM * JDIM * KDIM
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
'''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)'''
1000 CONTINUE
CLOSE ( IUNIT )
C
END
The program now produces one HDF5 file and one XML file for each iteration. Here is one
of the XML output files :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2">
<Domain>
<Grid Name="Demonstration Grid" GridType="Uniform">
<Topology TopologyType="Hexahedron" NumberOfElements="1680 " BaseOffset="1">
<DataItem Dimensions="13440 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Conns</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Dimensions="6435 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Points</DataItem>
</Geometry>
<Time TimeType="Single" Value="0.004"/>
<Attribute Name="Node Scalar" AttributeType="Scalar" Center="Node">
<DataItem Dimensions="2145 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/NodeData</DataItem>
</Attribute>
<Attribute Name="Cell Scalar" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="1680 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/CellData</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The final step would be to group
all of these together so we could animate them over time. Instead of duplicating the XML in another file for
each grid, we can use a little XML magic to pull them together :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0">
<Domain>
<Grid GridType="Collection" CollectionType="Temporal">
<xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
</Grid>
</Domain>
</Xdmf>
This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists
of the first (in our case, the only) grid in each file. This XML file could be generated programmtically
or by a post processing script.
f435025c6637027525f33dd109c1e42ca402c44d
Write from Fortran
0
10
51
50
2008-05-08T18:16:23Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf from Fortran ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider
the following Fortran program which build a grid of Hexahedra with some node and cell centered values :
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Grid of Hexahedron Centered at 0,0,0
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN )
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
INTEGER I, J, K, IDX
REAL*8 X, Y, Z, DX, DY, DZ
C Print *, 'Size = ', IDIM, JDIM, KDIM
PRINT *, 'Initialze Problem'
C XYZ Values of Nodes
C From -1 to 1
DX = 2.0 / ( IDIM - 1 )
DY = 2.0 / ( JDIM - 1 )
DZ = 2.0 / ( KDIM - 1 )
Z = -1.0
DO 112 K= 1, KDIM
Y = -1.0
DO 111 J= 1, JDIM
X = -1.0
DO 110 I= 1, IDIM
XYZ( 1, I, J, K ) = X
XYZ( 2, I, J, K ) = Y
XYZ( 3, I, J, K ) = Z
X = X + DX
110 CONTINUE
Y = Y + DY
111 CONTINUE
Z = Z + DZ
112 CONTINUE
C Connections
IDX = 1
DO 122 K= 0, KDIM - 2
DO 121 J= 0, JDIM - 2
DO 120 I= 1, IDIM - 1
ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I
ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I
IDX = IDX + 1
120 CONTINUE
121 CONTINUE
122 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Node Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
INTEGER I, J, K
REAL*8 X, Y, Z
PRINT *, 'Calculating Node Centered Data'
DO 212, K=1, KDIM
DO 211, J=1, JDIM
DO 210, I=1, IDIM
X = XYZ( 1, I, J, K )
Y = XYZ( 2, I, J, K )
Z = XYZ( 3, I, J, K )
NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z ))
210 CONTINUE
211 CONTINUE
212 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Cell Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
INTEGER IDIM, JDIM, KDIM, ITER, KICKER
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
INTEGER I, J, K
PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER
DO 312, K=1, KDIM - 1
DO 311, J=1, JDIM - 1
DO 310, I=1, IDIM - 1
X = XYZ( 1, I, J, K )
CCVALUES( I, J, K ) =
C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) /
C EXP( X / ( 1.0 * ITER ) )
310 CONTINUE
311 CONTINUE
312 CONTINUE
C Waste Time
DO 313 I=1, 1000000
X = 0.1 * ITER / I
Y = SQRT( X * X )
Z = EXP( Y )
313 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Main Program :
C Initialize Grid
C Initialize Node Centered Data
C For Iteration = 1 to 10
C Generate Cell Centered Data
C Done
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
PROGRAM HexMesh
PARAMETER ( IDIM = 11 )
PARAMETER ( JDIM = 13 )
PARAMETER ( KDIM = 15 )
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
C
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
C
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
C
INTEGER ITER, KICKER, NITER, NARG
INTEGER IUNIT
CHARACTER*80 ARGIN
C
NARG = IARGC()
IF( NARG .GE. 1 ) THEN
CALL GETARG( 1, ARGIN )
READ( ARGIN, '(I)') NITER
ELSE
NITER = 10
ENDIF
CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN )
CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
C
IUNIT = 14
OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) IDIM * JDIM * KDIM
WRITE ( IUNIT, * ) XYZ
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
WRITE ( IUNIT, * ) ICONN
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) NCVALUES
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' )
REWIND IUNIT
C
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now
let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML
via print statements (we could also shove bamboo shoots under our fingernails). A better approach
would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary
Xdmf calls to produce valid Xdmf XML and HDF5 files :
#include <Xdmf.h>
// We want the filenames to be based on the iteration
// and padded with zeros
using std::setw;
using std::setfill;
// This works with g77. Different compilers require different
// name mangling.
'''#define XdmfWrite xdmfwrite_'''
//
// C/C++ expect NULL terminated strings. Here is a conversion subroutine.
char *
DemoConvertFortranString( char *FtnName ) {
static char Name[80];
char *np;
memcpy(Name, FtnName, 79 );
Name[79] = '\0';
np = &Name[78];
while( ( np > Name ) && ( *np <= ' ') ) {
np--;
}
*np = '\0';
return( Name );
}
//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {
//
void
'''XdmfWrite(''' char *FtnName, int *Iteration,
int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points,
XdmfInt32 *Conns, XdmfFloat64 *NodeData,
XdmfFloat64 *CellData){
char *Name;
char FullName[80];
ostrstream DataName(FullName, 80);
XdmfDOM dom;
XdmfRoot root;
XdmfDomain domain;
XdmfGrid grid;
XdmfTime time;
XdmfTopology *topology;
XdmfGeometry *geometry;
XdmfAttribute nodedata;
XdmfAttribute celldata;
XdmfArray *array;
Name = DemoConvertFortranString( FtnName );
root.SetDOM(&dom);
root.SetVersion(2.0);
root.Build();
// Domain
root.Insert(&domain);
// Grid
grid.SetName("Demonstration Grid");
domain.Insert(&grid);
time.SetTimeType(XDMF_TIME_SINGLE);
time.SetValue(0.001 * *Iteration);
grid.Insert(&time);
// Topology
topology = grid.GetTopology();
topology->SetTopologyType(XDMF_HEX);
topology->SetNumberOfElements(*NumberOfHex);
// Fortran is 1 based while c++ is 0 based so
// Either subtract 1 from all connections or specify a BaseOffset
topology->SetBaseOffset(1);
// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
array = topology->GetConnectivity();
array->SetNumberOfElements(*NumberOfHex * 8);
array->SetValues(0, Conns, *NumberOfHex * 8);
// C++ string hocus pocus.
// We're actually building the string in FullName[] but were using streams.
// the DatasetName will be Demo_00001.h5:/Conns.
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends;
// Where the data will actually be written
array->SetHeavyDataSetName(FullName);
// Geometry
geometry = grid.GetGeometry();
geometry->SetGeometryType(XDMF_GEOMETRY_XYZ);
geometry->SetNumberOfPoints(*NumberOfPoints);
array = geometry->GetPoints();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetValues(0, Points, *NumberOfPoints * 3);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends;
array->SetHeavyDataSetName(FullName);
// Node Data
nodedata.SetName("Node Scalar");
nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = nodedata.GetValues();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetNumberOfElements(*NumberOfPoints);
array->SetValues(0, NodeData, *NumberOfPoints);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends;
array->SetHeavyDataSetName(FullName);
// Cell Data
celldata.SetName("Cell Scalar");
celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = celldata.GetValues();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetNumberOfElements(*NumberOfHex);
array->SetValues(0, CellData, *NumberOfHex);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends;
array->SetHeavyDataSetName(FullName);
// Attach and Write
grid.Insert(&nodedata);
grid.Insert(&celldata);
// Build is recursive ... it will be called on all of the child nodes.
// This updates the DOM and writes the HDF5
root.Build();
// Write the XML
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends;
dom.Write(FullName);
}
}
Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()'''
Original :
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Modified :
INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
INPNT = IDIM * JDIM * KDIM
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
'''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)'''
1000 CONTINUE
CLOSE ( IUNIT )
C
END
The program now produces one HDF5 file and one XML file for each iteration. Here is one
of the XML output files :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2">
<Domain>
<Grid Name="Demonstration Grid" GridType="Uniform">
<Topology TopologyType="Hexahedron" NumberOfElements="1680 " BaseOffset="1">
<DataItem Dimensions="13440 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Conns</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Dimensions="6435 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Points</DataItem>
</Geometry>
<Time TimeType="Single" Value="0.004"/>
<Attribute Name="Node Scalar" AttributeType="Scalar" Center="Node">
<DataItem Dimensions="2145 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/NodeData</DataItem>
</Attribute>
<Attribute Name="Cell Scalar" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="1680 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/CellData</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The final step would be to group
all of these together so we could animate them over time. Instead of duplicating the XML in another file for
each grid, we can use a little XML magic to pull them together :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0">
<Domain>
<Grid GridType="Collection" CollectionType="Temporal">
<xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
</Grid>
</Domain>
</Xdmf>
This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists
of the first (in our case, the only) grid in each file. This XML file could be generated programmtically
or by a post processing script.
9966b8b704f1a5d6a82cb3124e580f8ce14dbe3d
Main Page
0
1
52
46
2008-05-23T14:32:39Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
548626a3187be500fa743d5f2058abe039ac9b5f
56
52
2008-08-26T15:41:43Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
'''Mailing list'''
xdmf@lists.kitware.com
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
5d72f60ad4aaa8f798397bc01a426ba056ea3da5
62
56
2009-06-26T15:10:03Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Mailing list'''
xdmf@lists.kitware.com
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
3fffbeb2d3289cc7ba2f0b8433cb5161dace12a6
67
62
2009-06-26T15:29:07Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Perform Parallel IO with MPI]]
'''Mailing list'''
xdmf@lists.kitware.com
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
31b833957e22d6929eb20eb5dc7e79f47d204d0e
68
67
2009-06-26T16:15:20Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Mailing list'''
xdmf@lists.kitware.com
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
3fffbeb2d3289cc7ba2f0b8433cb5161dace12a6
74
68
2010-01-07T14:29:17Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
# [[Xdmf::New()]]
'''Mailing list'''
xdmf@lists.kitware.com
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
46709e5871480199dceee1da7b5fd7b47f9c563a
82
74
2011-01-18T13:53:58Z
Dave.partyka
10
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
# [[Xdmf::New()]]
'''Mailing list'''
Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf link here]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
390db7105838b205eee140053aab7c360dc87162
83
82
2011-01-18T13:54:13Z
Dave.partyka
10
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
# [[Xdmf::New()]]
'''Mailing list'''
Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
d68e31b55a531091b799085f62762f34d4115327
84
83
2011-01-18T13:55:37Z
Dave.partyka
10
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
# [[Xdmf::New()]]
'''Mailing list'''
# Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
8afc10d64121971ac2c78f0f6c8e00f72e81236c
87
84
2013-02-25T17:20:17Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
* [[Xdmf::New()]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Wiki Account'''
* To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
bc9daf7575d4197181fc1a3780921f7fac16e388
88
87
2013-02-25T17:32:00Z
Dave.demarle
5
Reverted edits by [[Special:Contributions/Dave.demarle|Dave.demarle]] ([[User_talk:Dave.demarle|Talk]]); changed back to last version by [[User:Dave.partyka|Dave.partyka]]
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
# [[Xdmf::New()]]
'''Mailing list'''
# Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
8afc10d64121971ac2c78f0f6c8e00f72e81236c
89
88
2013-02-25T17:33:36Z
Dave.demarle
5
Undo revision 88 by [[Special:Contributions/Dave.demarle]] ([[User talk:Dave.demarle]])
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
* [[Xdmf::New()]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Wiki Account'''
* To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
bc9daf7575d4197181fc1a3780921f7fac16e388
90
89
2013-03-01T08:31:11Z
Jk
12
added URL at which to report bugs about XDMF
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
* [[Xdmf::New()]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
'''Wiki Account'''
* To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
0bd62a687f5bb49584df30e28203b352c1dc319f
96
90
2014-07-25T18:31:53Z
Imikejackson
18
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''What's Next'''
* [[Xdmf::New()]]
'''Version 3 Feature Request'''
* [[V3_Road_Feature_Request]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
'''Wiki Account'''
* To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
c209749a55f7c96ccf86f840f6bb94108cd432bb
97
96
2014-08-19T18:14:08Z
Dave.demarle
5
start updating to xdmf3 and adding more useful content
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Examples'''
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Xdmf::New()|'''What's Next''']]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
'''Wiki Account'''
* To edit these pages, send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
53a5f4a30a029682e1888fdbf093c08f7c30d54e
99
97
2014-08-19T18:37:31Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Xdmf::New()|'''What's Next''']]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* To edit these pages, send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
5806c3bbcdde6c477b08195ee0254ff345c00f86
Read from MySQL
0
11
53
2008-05-23T14:37:21Z
Jerry
2
New page: == '''Accessing a MySQL DataBase''' == Partial support for reading data from a MySQL database is available. MySQL is treated as another HeavyData format like HDF5. Currently database acce...
wikitext
text/x-wiki
== '''Accessing a MySQL DataBase''' ==
Partial support for reading data from a MySQL database is available.
MySQL is treated as another HeavyData format like HDF5. Currently
database access is ReadOnly and is accessed by setting the '''Format''' of
the '''DataItem''' in XML equal to '''MySQL'''
<Attribute Name="Cell Centered Values" Center="Cell">
<DataItem Format="MySQL"
Server="localhost"
User="root"
DataBase="MnmiFromout"
Dimensions="3"
NumberType="Float">
<![CDATA[SELECT X FROM Locations WHERE Time < 0.21]]>
</DataItem>
</Attribute>
ef062d9c828e7034750dc454e9ba71a82080e911
54
53
2008-05-23T14:44:03Z
Jerry
2
wikitext
text/x-wiki
== '''Accessing a MySQL DataBase''' ==
Partial support for reading data from a MySQL database is available.
MySQL is treated as another HeavyData format like HDF5. Currently
database access is ReadOnly and is accessed by setting the '''Format''' of
the '''DataItem''' in XML equal to '''MySQL'''
<Attribute Name="Cell Centered Values" Center="Cell">
<DataItem Format="MySQL"
Server="localhost"
User="root"
DataBase="MnmiFromout"
Dimensions="3"
NumberType="Float">
<![CDATA[SELECT X FROM Locations WHERE Time < 0.21]]>
</DataItem>
</Attribute>
A Valid SQL statement is placed in the CDATA of the DataItem. When the XdmfDataItem is
updated, an atomic query is made and the result is placed in the XdmfArray of the DataItem.
Putting a "<" (less than) in the CDATA will cause an error in the XML parser. The XML example
above shows how to do this correctly.
The Server, User, and DataBase attributes tell Xdmf how to access MySQL. There is also
a Password attribute. Currently this is just clear text which is a really bad idea. This
will change.
0a92c614bc7e98a07ec0e028155cb19a2035ca4e
XDMF API
0
3
55
44
2008-07-24T23:35:23Z
Berk
4
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
ba1233a3c254f628c8e2262a0c99372e321105bc
XDMF Model and Format
0
2
57
45
2008-09-30T16:03:26Z
Jerry
2
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
339024a9c3c48ee1e9b0f1f7c466b384689dd34b
73
57
2009-09-16T17:51:20Z
Dave.demarle
5
update to mention globalid attribute
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
f20f7c57ce83963ffe8cba1bc9ab9bc3ea67f449
85
73
2011-10-28T19:14:11Z
Dave.demarle
5
document binary heavy data format
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian Native | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek bytes (applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
f1753c889a858f8414faeae5388dce5915f90272
86
85
2011-10-28T19:17:29Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
936ea1357ce3ee16dc295b2fa1b9ad3fcc5cc4eb
91
86
2013-03-01T09:11:51Z
Jk
12
added small section and example regarding XML entities.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
05d341521ee6e3e137c45f99954b60b56f3c9971
92
91
2013-03-01T09:17:39Z
Jk
12
added reference to Origin_DxDy where Origin_DxDyDz is mentioned
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Or '''
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
dd17931d0bfc897d775af0af7134005870224140
93
92
2013-04-03T11:49:48Z
Jk
12
two minor corrections on code blocks (one split and two joined)
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | <span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
68d0cc630b1532f6b733bf4c46dc4fb2b5231707
94
93
2014-07-25T17:45:35Z
Imikejackson
18
Adding update for 16 bit integer writing
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
dbfc6f7c2523db7dc46fae5158a538785450a26e
Write Xdmf
0
9
58
49
2009-01-23T13:30:02Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetShapeFromString("10 20 30")
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
~
c352d0c23ffc049c89f649508391b44b3d580f0b
59
58
2009-01-23T20:41:30Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetShapeFromString("10 20 30")
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner.
All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is
built, the XML is blindly copied in and the writing of HeavyData is skipped.
#!/usr/bin/env python
from Xdmf import *
# Example of How to Generate Xdmf
# The Heavy Data for the Attribute is written separately
# Write H5 Data
arr = XdmfArray()
arr.SetNumberType(XDMF_FLOAT64_TYPE)
arr.SetShapeFromString("10 20 30")
arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1)
h5 = XdmfHDF()
h5.CopyType(arr)
h5.CopyShape(arr)
h5.Open('XdmfByHand.h5:/Mydata', 'w')
h5.Write(arr)
h5.Close()
DataXml = """<DataItem
Dimensions="10 20 30"
NumberType="Float"
Precision="8"
Format="HDF">
XdmfByHand.h5:/Mydata
</DataItem>"""
#
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
# Insert the raw XML
attr.SetDataXml(DataXml)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
This results in identical XML with just the name of the HDF5 dataset changed.
~
76e395d21b1a554317289c4d5d45505f148c2fbe
60
59
2009-01-23T20:42:11Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetShapeFromString("10 20 30")
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner.
All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is
built, the XML is blindly copied in and the writing of HeavyData is skipped.
#!/usr/bin/env python
from Xdmf import *
# Example of How to Generate Xdmf
# The Heavy Data for the Attribute is written separately
# Write H5 Data
arr = XdmfArray()
arr.SetNumberType(XDMF_FLOAT64_TYPE)
arr.SetShapeFromString("10 20 30")
arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1)
h5 = XdmfHDF()
h5.CopyType(arr)
h5.CopyShape(arr)
h5.Open('XdmfByHand.h5:/Mydata', 'w')
h5.Write(arr)
h5.Close()
DataXml = """<DataItem
Dimensions="10 20 30"
NumberType="Float"
Precision="8"
Format="HDF">
XdmfByHand.h5:/Mydata
</DataItem>"""
#
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
# Insert the raw XML
attr.SetDataXml(DataXml)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
This results in identical XML with just the name of the HDF5 dataset changed.
~
1d0aa9675411d278bebd5899d817b2cf84652e92
61
60
2009-01-26T21:22:19Z
Jerry
2
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetShapeFromString("10 20 30")
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner.
All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is
built, the XML is blindly copied in and the writing of HeavyData is skipped.
#!/usr/bin/env python
from Xdmf import *
# Example of How to Generate Xdmf
# The Heavy Data for the Attribute is written separately
# Write H5 Data
arr = XdmfArray()
arr.SetNumberType(XDMF_FLOAT64_TYPE)
arr.SetShapeFromString("10 20 30")
arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1)
h5 = XdmfHDF()
h5.CopyType(arr)
h5.CopyShape(arr)
h5.Open('XdmfByHand.h5:/Mydata', 'w')
h5.Write(arr)
h5.Close()
# Use XdmfValuesHDF to generate the appropriate
# Xdmf XML from and existing HDF5 dataset
dv = XdmfValuesHDF()
DataXml = dv.DataItemFromHDF('XdmfByHand.h5:/Mydata')
#
# Now build the tree of objects
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
# Insert the raw XML
attr.SetDataXml(DataXml)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
This results in identical XML with just the name of the HDF5 dataset changed.
~
ba7310e7f381f341364c895900649b81600b5192
Parallel IO with MPI
0
12
63
2009-06-26T15:12:30Z
Jerry
2
New page: (code and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be writ...
wikitext
text/x-wiki
(code and description provided by Will Dicharry)
=== Controlling the I/O process for XdmfHeavyData ===
The XDMF API provides a customization point to allow the heavy data sets
to be written in a certain manner, depending on the application
environment and independent of the heavy dataset format. New I/O
strategies can be implemented by subclassing the callback classes
defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes.
This method has the advantage of applying a common strategy to any
XdmfHeavyData subclass.
The system works in the following way:
XdmfHeavyData contains the non-virtual methods Open, Close, Read, and
Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite.
XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment.
In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely.
=== Example ===
Suppose we have an MPI environment with 4 processes. Each process
contains part of an array with 100 values numbered 0 to 99; process 0
with items 0-24, process 1 with items 25-49, etc. We would like to
write this data to a single HDF file containing a single array of 100
values, stored in increasing numerical order. To do this, we will
communicate all of the data to process 0 and let process 0 handle the
actual output of the array.
We start by including the necessary headers and defining a very simple
stream buffer utility class that simplifies encoding and decoding data
between processes:
<code>
#include <mpi.h>
#include <XdmfArray.h>
#include <XdmfHDF.h>
/// Simple memory buffer implementation that keeps track of it's stream pointer.
class Buffer {
private:
std::size_t m_size;
char* m_data;
char* m_put;
char* m_tell;
public:
Buffer( std::size_t size ) :
m_size( size ),
m_data( new char[size] ),
m_put( m_data ),
m_tell( m_data )
{}
~Buffer() {
delete [] m_data;
}
/// copy a contiguous block into the buffer
void put( const void* data, std::size_t size ) {
memcpy( m_put, data, size );
m_put += size;
}
/// put a single value into the buffer
template< typename T >
void put( const T& t ) {
std::size_t size = sizeof( T );
put( &t, size );
}
/// copy a contiguous block of data from the buffer to an already
/// allocated location
void tell( void* out, std::size_t size ) {
memcpy( out, m_tell, size );
m_tell += size;
}
/// Copy a single value into the buffer.
template< typename T >
T tell() {
std::size_t tsize = sizeof( T );
T tmp;
tell( &tmp, tsize );
return tmp;
}
std::size_t size() const {
return m_size;
}
char* pointer() {
return m_data;
}
void reset() {
m_put = m_data;
m_tell = m_data;
}
};
</code>
We haven't yet called on the Xdmf API to do anything, the Buffer class
is just a utility that we will use later.
Now, we write our callback class that will customize the process of
opening, reading, writing, and closing the heavy dataset. Since our
communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback,
XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes
has a single virtual method that takes a pointer to a XdmfHeavyData and
the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close,
XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods.
<code>
/// Callback implements parallel IO by communicating to process 0
class CommunicationCallback :
public XdmfOpenCallback,
public XdmfWriteCallback,
public XdmfCloseCallback,
public XdmfReadCallback
{
private:
int mCommRank;
int mCommSize;
public:
/// Constructor initializes the Number of processors and local process
/// ID.
CommunicationCallback() {
MPI_Comm_size( MPI_COMM_WORLD, &mCommSize );
MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank );
}
/// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going
/// to read or write, so only rank 0 will open the file.
XdmfInt32 DoOpen(
XdmfHeavyData* ds,
XdmfConstString name,
XdmfConstString access )
{
if ( mCommRank == 0 ) {
// Call the actual DoOpen method from XdmfHeavyData
return ds->DoOpen( name, access );
} else {
// Not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0
/// needs to do anything.
XdmfInt32 DoClose( XdmfHeavyData* ds )
{
if ( mCommRank == 0 ) {
// Call the heavy dataset's native close method.
return ds->DoClose();
} else {
// not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfWriteCallback::DoWrite. If the local
/// process ID is 0, then we expect to receive data from everyone
/// else. Otherwise, we send data. Rank 0 does all of the writing.
XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array )
{
// This implementation assumes process 0 has the same data
// size as everyone else
// set up a stream buffer that is large enough to hold the data to
// be sent or received. We require enough space for the rank,
// start, stride, and count for the array plus enough space to hold
// the actual array data.
XdmfInt64 start[1], stride[1], count[1];
XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count );
std::size_t slab_info_size =
sizeof( XdmfInt32 ) // slab rank
+ slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count
Buffer buf( slab_info_size + array->GetCoreLength() );
// If the local process ID is nonzero, pack the buffer and send to
// process 0.
if ( mCommRank != 0 ) {
// copy rank and slab information into the buffer.
buf.put( slab_rank );
for ( int i = 0; i < slab_rank; ++i ) {
buf.put( start[i] );
buf.put( stride[i] );
buf.put( count[i] );
}
// copy the actual data into the buffer.
buf.put( array->GetDataPointer(), array->GetCoreLength() );
// send to rank 0 in the global communicator.
MPI_Send(
buf.pointer(),
buf.size(),
MPI_BYTE,
0,
0,
MPI_COMM_WORLD );
} else {
// Local process ID is 0, so we write local data then receive and
// write remote data.
// first, it's easy to write the local data
ds->DoWrite( array );
int processes_received = 1; // local data for process 0 is written
// loop until the data for all processes has been received.
while ( processes_received < mCommSize ) {
// Fill the buffer with incoming data. We are assuming here
// that all processes contain the same amount of data.
MPI_Recv(
buf.pointer(),
buf.size(),
MPI_BYTE,
MPI_ANY_SOURCE,
0,
MPI_COMM_WORLD,
0 );
processes_received++;
// unpack the buffer
buf.reset(); // reset the stream pointer to the beginning
// we mean rank in the linear algebra sense here
slab_rank = buf.tell< XdmfInt32 >();
// start, stride, and count are next.
for( int i = 0; i < slab_rank; ++i ) {
start[i] = buf.tell< XdmfInt64 >();
stride[i] = buf.tell< XdmfInt64 >();
count[i] = buf.tell< XdmfInt64 >();
}
// select the correct hyper slab in the heavy data set.
ds->SelectHyperSlab( start, stride, count );
// allocate an array to hold the off-core data.
XdmfArray* recv = new XdmfArray;
recv->CopyShape( array );
// place the received data into the array.
buf.tell( recv->GetDataPointer(), recv->GetCoreLength() );
// write the off core data to the dataset by calling the heavy
// data's DoWrite method.
ds->DoWrite( recv );
delete recv;
}
}
return XDMF_SUCCESS;
}
/// Reimplemented from XdmfReadCallback::DoRead. Read the data from a
/// heavy data source into an array only if the local process ID is 0.
/// Otherwise, do nothing.
XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array )
{
if ( mCommRank == 0 ) {
// defer to the actual heavy data implementation of DoRead.
return ds->DoRead( array );
} else {
// return an empty array.
return NULL;
}
}
}; // end of class CommunicationCallback
</code>
One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well.
Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip.
<code>
char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI";
int main( int argc, char* argv[] ) {
// Initialize MPI
MPI_Init( &argc, &argv );
// determine the local process ID
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// Create an HDF dataset to write out to.
XdmfHDF* H5 = new XdmfHDF();
// Attach an instance of the CommunicationCallback class defined above
// to customize opening, writing, and closing the dataset.
CommunicationCallback* cb = new CommunicationCallback;
H5->setOpenCallback( cb );
H5->setWriteCallback( cb );
H5->setCloseCallback(cb );
// Allocate an array of size 25 and fill it with values depending
// on the local process ID (process 0 has 0-24, process 1 has
// 25-49,...)
XdmfArray* MyData = new XdmfArray();
MyData->SetNumberType( XDMF_FLOAT32_TYPE );
MyData->SetNumberOfElements( 25 );
MyData->Generate( rank * 25, rank*25 + 24 );
// Set the dataset's type to the array's type
H5->CopyType( MyData );
// Set up the dimensions of the dataset.
XdmfInt64 dims[1];
dims[0] = 100;
H5->SetShape( 1, dims );
// Set up the hyper slab for the dataset. Each process will select a
// distinct portion of the dataset (process 0 has 0-24, process 1
// 25-49,...)
XdmfInt64 start[1], stride[1], count[1];
start[0] = rank * 25;
stride[0] = 1;
count[0] = 25;
// select the slab in the dataset corresponding to the local process.
H5->SelectHyperSlab( start, stride, count );
// Open the dataset.
H5->Open( kDatasetName, "w" );
// Write the array.
H5->Write( MyData );
// Close the dataset.
H5->Close();
// writing is complete, now we have a quick test to ensure the data
// survives a round trip.
bool failure = false;
// Create a new dataset to read from
XdmfHDF* H5In = new XdmfHDF();
// Use the same callback.
H5In->setReadCallback( cb );
H5In->setOpenCallback( cb );
H5In->setCloseCallback( cb );
// Open the dataset for reading.
H5In->Open( kDatasetName, "r" );
// Read the data into an array.
XdmfArray* result = H5In->Read();
// if the read was successful, make sure the values for all processes
// are in the file.
if ( result ) {
for ( size_t i = 0; i < 100; ++i ) {
float value = result->GetValueAsFloat32( i );
std::cout << i << " " << value << std::endl;
failure = ( value != i );
}
}
MPI_Finalize();
delete H5;
delete cb;
delete MyData;
delete H5In;
delete result;
if ( failure ) {
return -1;
} else {
return 0;
}
};
</code>
Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree.
4a4160c219990d594aaff0ecb081a4ea2c6ce30c
64
63
2009-06-26T15:15:14Z
Jerry
2
wikitext
text/x-wiki
(code and description provided by Will Dicharry)
=== Controlling the I/O process for XdmfHeavyData ===
The XDMF API provides a customization point to allow the heavy data sets
to be written in a certain manner, depending on the application
environment and independent of the heavy dataset format. New I/O
strategies can be implemented by subclassing the callback classes
defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes.
This method has the advantage of applying a common strategy to any
XdmfHeavyData subclass.
The system works in the following way:
XdmfHeavyData contains the non-virtual methods Open, Close, Read, and
Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite.
XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment.
In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely.
=== Example ===
Suppose we have an MPI environment with 4 processes. Each process
contains part of an array with 100 values numbered 0 to 99; process 0
with items 0-24, process 1 with items 25-49, etc. We would like to
write this data to a single HDF file containing a single array of 100
values, stored in increasing numerical order. To do this, we will
communicate all of the data to process 0 and let process 0 handle the
actual output of the array.
We start by including the necessary headers and defining a very simple
stream buffer utility class that simplifies encoding and decoding data
between processes:
<code>
#include <mpi.h>
#include <XdmfArray.h>
#include <XdmfHDF.h>
/// Simple memory buffer implementation that keeps track of it's stream pointer.
class Buffer {
private:
std::size_t m_size;
char* m_data;
char* m_put;
char* m_tell;
public:
Buffer( std::size_t size ) :
m_size( size ),
m_data( new char[size] ),
m_put( m_data ),
m_tell( m_data )
{}
~Buffer() {
delete [] m_data;
}
/// copy a contiguous block into the buffer
void put( const void* data, std::size_t size ) {
memcpy( m_put, data, size );
m_put += size;
}
/// put a single value into the buffer
template< typename T >
void put( const T& t ) {
std::size_t size = sizeof( T );
put( &t, size );
}
/// copy a contiguous block of data from the buffer to an already
/// allocated location
void tell( void* out, std::size_t size ) {
memcpy( out, m_tell, size );
m_tell += size;
}
/// Copy a single value into the buffer.
template< typename T >
T tell() {
std::size_t tsize = sizeof( T );
T tmp;
tell( &tmp, tsize );
return tmp;
}
std::size_t size() const {
return m_size;
}
char* pointer() {
return m_data;
}
void reset() {
m_put = m_data;
m_tell = m_data;
}
};
</code>
We haven't yet called on the Xdmf API to do anything, the Buffer class
is just a utility that we will use later.
Now, we write our callback class that will customize the process of
opening, reading, writing, and closing the heavy dataset. Since our
communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback,
XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes
has a single virtual method that takes a pointer to a XdmfHeavyData and
the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close,
XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods.
<code>
/// Callback implements parallel IO by communicating to process 0
class CommunicationCallback :
public XdmfOpenCallback,
public XdmfWriteCallback,
public XdmfCloseCallback,
public XdmfReadCallback
{
private:
int mCommRank;
int mCommSize;
public:
/// Constructor initializes the Number of processors and local process
/// ID.
CommunicationCallback() {
MPI_Comm_size( MPI_COMM_WORLD, &mCommSize );
MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank );
}
/// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going
/// to read or write, so only rank 0 will open the file.
XdmfInt32 DoOpen(
XdmfHeavyData* ds,
XdmfConstString name,
XdmfConstString access )
{
if ( mCommRank == 0 ) {
// Call the actual DoOpen method from XdmfHeavyData
return ds->DoOpen( name, access );
} else {
// Not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0
/// needs to do anything.
XdmfInt32 DoClose( XdmfHeavyData* ds )
{
if ( mCommRank == 0 ) {
// Call the heavy dataset's native close method.
return ds->DoClose();
} else {
// not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfWriteCallback::DoWrite. If the local
/// process ID is 0, then we expect to receive data from everyone
/// else. Otherwise, we send data. Rank 0 does all of the writing.
XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array )
{
// This implementation assumes process 0 has the same data
// size as everyone else
// set up a stream buffer that is large enough to hold the data to
// be sent or received. We require enough space for the rank,
// start, stride, and count for the array plus enough space to hold
// the actual array data.
XdmfInt64 start[1], stride[1], count[1];
XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count );
std::size_t slab_info_size =
sizeof( XdmfInt32 ) // slab rank
+ slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count
Buffer buf( slab_info_size + array->GetCoreLength() );
// If the local process ID is nonzero, pack the buffer and send to
// process 0.
if ( mCommRank != 0 ) {
// copy rank and slab information into the buffer.
buf.put( slab_rank );
for ( int i = 0; i < slab_rank; ++i ) {
buf.put( start[i] );
buf.put( stride[i] );
buf.put( count[i] );
}
// copy the actual data into the buffer.
buf.put( array->GetDataPointer(), array->GetCoreLength() );
// send to rank 0 in the global communicator.
MPI_Send(
buf.pointer(),
buf.size(),
MPI_BYTE,
0,
0,
MPI_COMM_WORLD );
} else {
// Local process ID is 0, so we write local data then receive and
// write remote data.
// first, it's easy to write the local data
ds->DoWrite( array );
int processes_received = 1; // local data for process 0 is written
// loop until the data for all processes has been received.
while ( processes_received < mCommSize ) {
// Fill the buffer with incoming data. We are assuming here
// that all processes contain the same amount of data.
MPI_Recv(
buf.pointer(),
buf.size(),
MPI_BYTE,
MPI_ANY_SOURCE,
0,
MPI_COMM_WORLD,
0 );
processes_received++;
// unpack the buffer
buf.reset(); // reset the stream pointer to the beginning
// we mean rank in the linear algebra sense here
slab_rank = buf.tell< XdmfInt32 >();
// start, stride, and count are next.
for( int i = 0; i < slab_rank; ++i ) {
start[i] = buf.tell< XdmfInt64 >();
stride[i] = buf.tell< XdmfInt64 >();
count[i] = buf.tell< XdmfInt64 >();
}
// select the correct hyper slab in the heavy data set.
ds->SelectHyperSlab( start, stride, count );
// allocate an array to hold the off-core data.
XdmfArray* recv = new XdmfArray;
recv->CopyShape( array );
// place the received data into the array.
buf.tell( recv->GetDataPointer(), recv->GetCoreLength() );
// write the off core data to the dataset by calling the heavy
// data's DoWrite method.
ds->DoWrite( recv );
delete recv;
}
}
return XDMF_SUCCESS;
}
/// Reimplemented from XdmfReadCallback::DoRead. Read the data from a
/// heavy data source into an array only if the local process ID is 0.
/// Otherwise, do nothing.
XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array )
{
if ( mCommRank == 0 ) {
// defer to the actual heavy data implementation of DoRead.
return ds->DoRead( array );
} else {
// return an empty array.
return NULL;
}
}
}; // end of class CommunicationCallback
</code>
One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well.
Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip.
<code>
char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI";
int main( int argc, char* argv[] ) {
// Initialize MPI
MPI_Init( &argc, &argv );
// determine the local process ID
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// Create an HDF dataset to write out to.
XdmfHDF* H5 = new XdmfHDF();
// Attach an instance of the CommunicationCallback class defined above
// to customize opening, writing, and closing the dataset.
CommunicationCallback* cb = new CommunicationCallback;
H5->setOpenCallback( cb );
H5->setWriteCallback( cb );
H5->setCloseCallback(cb );
// Allocate an array of size 25 and fill it with values depending
// on the local process ID (process 0 has 0-24, process 1 has
// 25-49,...)
XdmfArray* MyData = new XdmfArray();
MyData->SetNumberType( XDMF_FLOAT32_TYPE );
MyData->SetNumberOfElements( 25 );
MyData->Generate( rank * 25, rank*25 + 24 );
// Set the dataset's type to the array's type
H5->CopyType( MyData );
// Set up the dimensions of the dataset.
XdmfInt64 dims[1];
dims[0] = 100;
H5->SetShape( 1, dims );
// Set up the hyper slab for the dataset. Each process will select a
// distinct portion of the dataset (process 0 has 0-24, process 1
// 25-49,...)
XdmfInt64 start[1], stride[1], count[1];
start[0] = rank * 25;
stride[0] = 1;
count[0] = 25;
// select the slab in the dataset corresponding to the local process.
H5->SelectHyperSlab( start, stride, count );
// Open the dataset.
H5->Open( kDatasetName, "w" );
// Write the array.
H5->Write( MyData );
// Close the dataset.
H5->Close();
// writing is complete, now we have a quick test to ensure the data
// survives a round trip.
bool failure = false;
// Create a new dataset to read from
XdmfHDF* H5In = new XdmfHDF();
// Use the same callback.
H5In->setReadCallback( cb );
H5In->setOpenCallback( cb );
H5In->setCloseCallback( cb );
// Open the dataset for reading.
H5In->Open( kDatasetName, "r" );
// Read the data into an array.
XdmfArray* result = H5In->Read();
// if the read was successful, make sure the values for all processes
// are in the file.
if ( result ) {
for ( size_t i = 0; i < 100; ++i ) {
float value = result->GetValueAsFloat32( i );
std::cout << i << " " << value << std::endl;
failure = ( value != i );
}
}
MPI_Finalize();
delete H5;
delete cb;
delete MyData;
delete H5In;
delete result;
if ( failure ) {
return -1;
} else {
return 0;
}
};
</code>
Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree.
6fa0c1c2a5b45003677b5c63de891cdcd6a7ea95
65
64
2009-06-26T15:17:04Z
Jerry
2
wikitext
text/x-wiki
(code and description provided by Will Dicharry)
=== Controlling the I/O process for XdmfHeavyData ===
The XDMF API provides a customization point to allow the heavy data sets
to be written in a certain manner, depending on the application
environment and independent of the heavy dataset format. New I/O
strategies can be implemented by subclassing the callback classes
defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes.
This method has the advantage of applying a common strategy to any
XdmfHeavyData subclass.
The system works in the following way:
XdmfHeavyData contains the non-virtual methods Open, Close, Read, and
Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite.
XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment.
In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely.
=== Example ===
Suppose we have an MPI environment with 4 processes. Each process
contains part of an array with 100 values numbered 0 to 99; process 0
with items 0-24, process 1 with items 25-49, etc. We would like to
write this data to a single HDF file containing a single array of 100
values, stored in increasing numerical order. To do this, we will
communicate all of the data to process 0 and let process 0 handle the
actual output of the array.
We start by including the necessary headers and defining a very simple
stream buffer utility class that simplifies encoding and decoding data
between processes:
<code>
#include <mpi.h>
#include <XdmfArray.h>
#include <XdmfHDF.h>
/// Simple memory buffer implementation that keeps track of it's stream pointer.
class Buffer {
private:
std::size_t m_size;
char* m_data;
char* m_put;
char* m_tell;
public:
Buffer( std::size_t size ) :
m_size( size ),
m_data( new char[size] ),
m_put( m_data ),
m_tell( m_data )
{}
~Buffer() {
delete [] m_data;
}
/// copy a contiguous block into the buffer
void put( const void* data, std::size_t size ) {
memcpy( m_put, data, size );
m_put += size;
}
/// put a single value into the buffer
template< typename T >
void put( const T& t ) {
std::size_t size = sizeof( T );
put( &t, size );
}
/// copy a contiguous block of data from the buffer to an already
/// allocated location
void tell( void* out, std::size_t size ) {
memcpy( out, m_tell, size );
m_tell += size;
}
/// Copy a single value into the buffer.
template< typename T >
T tell() {
std::size_t tsize = sizeof( T );
T tmp;
tell( &tmp, tsize );
return tmp;
}
std::size_t size() const {
return m_size;
}
char* pointer() {
return m_data;
}
void reset() {
m_put = m_data;
m_tell = m_data;
}
};
</code>
We haven't yet called on the Xdmf API to do anything, the Buffer class
is just a utility that we will use later.
Now, we write our callback class that will customize the process of
opening, reading, writing, and closing the heavy dataset. Since our
communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback,
XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes
has a single virtual method that takes a pointer to a XdmfHeavyData and
the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close,
XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods.
<code>
/// Callback implements parallel IO by communicating to process 0
class CommunicationCallback :
public XdmfOpenCallback,
public XdmfWriteCallback,
public XdmfCloseCallback,
public XdmfReadCallback
{
private:
int mCommRank;
int mCommSize;
public:
/// Constructor initializes the Number of processors and local process
/// ID.
CommunicationCallback() {
MPI_Comm_size( MPI_COMM_WORLD, &mCommSize );
MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank );
}
/// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going
/// to read or write, so only rank 0 will open the file.
XdmfInt32 DoOpen(
XdmfHeavyData* ds,
XdmfConstString name,
XdmfConstString access )
{
if ( mCommRank == 0 ) {
// Call the actual DoOpen method from XdmfHeavyData
return ds->DoOpen( name, access );
} else {
// Not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0
/// needs to do anything.
XdmfInt32 DoClose( XdmfHeavyData* ds )
{
if ( mCommRank == 0 ) {
// Call the heavy dataset's native close method.
return ds->DoClose();
} else {
// not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfWriteCallback::DoWrite. If the local
/// process ID is 0, then we expect to receive data from everyone
/// else. Otherwise, we send data. Rank 0 does all of the writing.
XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array )
{
// This implementation assumes process 0 has the same data
// size as everyone else
// set up a stream buffer that is large enough to hold the data to
// be sent or received. We require enough space for the rank,
// start, stride, and count for the array plus enough space to hold
// the actual array data.
XdmfInt64 start[1], stride[1], count[1];
XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count );
std::size_t slab_info_size =
sizeof( XdmfInt32 ) // slab rank
+ slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count
Buffer buf( slab_info_size + array->GetCoreLength() );
// If the local process ID is nonzero, pack the buffer and send to
// process 0.
if ( mCommRank != 0 ) {
// copy rank and slab information into the buffer.
buf.put( slab_rank );
for ( int i = 0; i < slab_rank; ++i ) {
buf.put( start[i] );
buf.put( stride[i] );
buf.put( count[i] );
}
// copy the actual data into the buffer.
buf.put( array->GetDataPointer(), array->GetCoreLength() );
// send to rank 0 in the global communicator.
MPI_Send(
buf.pointer(),
buf.size(),
MPI_BYTE,
0,
0,
MPI_COMM_WORLD );
} else {
// Local process ID is 0, so we write local data then receive and
// write remote data.
// first, it's easy to write the local data
ds->DoWrite( array );
int processes_received = 1; // local data for process 0 is written
// loop until the data for all processes has been received.
while ( processes_received < mCommSize ) {
// Fill the buffer with incoming data. We are assuming here
// that all processes contain the same amount of data.
MPI_Recv(
buf.pointer(),
buf.size(),
MPI_BYTE,
MPI_ANY_SOURCE,
0,
MPI_COMM_WORLD,
0 );
processes_received++;
// unpack the buffer
buf.reset(); // reset the stream pointer to the beginning
// we mean rank in the linear algebra sense here
slab_rank = buf.tell< XdmfInt32 >();
// start, stride, and count are next.
for( int i = 0; i < slab_rank; ++i ) {
start[i] = buf.tell< XdmfInt64 >();
stride[i] = buf.tell< XdmfInt64 >();
count[i] = buf.tell< XdmfInt64 >();
}
// select the correct hyper slab in the heavy data set.
ds->SelectHyperSlab( start, stride, count );
// allocate an array to hold the off-core data.
XdmfArray* recv = new XdmfArray;
recv->CopyShape( array );
// place the received data into the array.
buf.tell( recv->GetDataPointer(), recv->GetCoreLength() );
// write the off core data to the dataset by calling the heavy
// data's DoWrite method.
ds->DoWrite( recv );
delete recv;
}
}
return XDMF_SUCCESS;
}
/// Reimplemented from XdmfReadCallback::DoRead. Read the data from a
/// heavy data source into an array only if the local process ID is 0.
/// Otherwise, do nothing.
XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array )
{
if ( mCommRank == 0 ) {
// defer to the actual heavy data implementation of DoRead.
return ds->DoRead( array );
} else {
// return an empty array.
return NULL;
}
}
}; // end of class CommunicationCallback
</code>
One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well.
Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip.
<code>
char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI";
int main( int argc, char* argv[] ) {
// Initialize MPI
MPI_Init( &argc, &argv );
// determine the local process ID
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// Create an HDF dataset to write out to.
XdmfHDF* H5 = new XdmfHDF();
// Attach an instance of the CommunicationCallback class defined above
// to customize opening, writing, and closing the dataset.
CommunicationCallback* cb = new CommunicationCallback;
H5->setOpenCallback( cb );
H5->setWriteCallback( cb );
H5->setCloseCallback(cb );
// Allocate an array of size 25 and fill it with values depending
// on the local process ID (process 0 has 0-24, process 1 has
// 25-49,...)
XdmfArray* MyData = new XdmfArray();
MyData->SetNumberType( XDMF_FLOAT32_TYPE );
MyData->SetNumberOfElements( 25 );
MyData->Generate( rank * 25, rank*25 + 24 );
// Set the dataset's type to the array's type
H5->CopyType( MyData );
// Set up the dimensions of the dataset.
XdmfInt64 dims[1];
dims[0] = 100;
H5->SetShape( 1, dims );
// Set up the hyper slab for the dataset. Each process will select a
// distinct portion of the dataset (process 0 has 0-24, process 1
// 25-49,...)
XdmfInt64 start[1], stride[1], count[1];
start[0] = rank * 25;
stride[0] = 1;
count[0] = 25;
// select the slab in the dataset corresponding to the local process.
H5->SelectHyperSlab( start, stride, count );
// Open the dataset.
H5->Open( kDatasetName, "w" );
// Write the array.
H5->Write( MyData );
// Close the dataset.
H5->Close();
// writing is complete, now we have a quick test to ensure the data
// survives a round trip.
bool failure = false;
// Create a new dataset to read from
XdmfHDF* H5In = new XdmfHDF();
// Use the same callback.
H5In->setReadCallback( cb );
H5In->setOpenCallback( cb );
H5In->setCloseCallback( cb );
// Open the dataset for reading.
H5In->Open( kDatasetName, "r" );
// Read the data into an array.
XdmfArray* result = H5In->Read();
// if the read was successful, make sure the values for all processes
// are in the file.
if ( result ) {
for ( size_t i = 0; i < 100; ++i ) {
float value = result->GetValueAsFloat32( i );
std::cout << i << " " << value << std::endl;
failure = ( value != i );
}
}
MPI_Finalize();
delete H5;
delete cb;
delete MyData;
delete H5In;
delete result;
if ( failure ) {
return -1;
} else {
return 0;
}
};
</code>
Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree.
40e09c3994cb23ffd3f8b0eee01a1e7cb04bad9f
66
65
2009-06-26T15:19:01Z
Jerry
2
wikitext
text/x-wiki
(code and description provided by Will Dicharry)
=== Controlling the I/O process for XdmfHeavyData ===
The XDMF API provides a customization point to allow the heavy data sets
to be written in a certain manner, depending on the application
environment and independent of the heavy dataset format. New I/O
strategies can be implemented by subclassing the callback classes
defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes.
This method has the advantage of applying a common strategy to any
XdmfHeavyData subclass.
The system works in the following way:
XdmfHeavyData contains the non-virtual methods Open, Close, Read, and
Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite.
XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment.
In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely.
=== Example ===
Suppose we have an MPI environment with 4 processes. Each process
contains part of an array with 100 values numbered 0 to 99; process 0
with items 0-24, process 1 with items 25-49, etc. We would like to
write this data to a single HDF file containing a single array of 100
values, stored in increasing numerical order. To do this, we will
communicate all of the data to process 0 and let process 0 handle the
actual output of the array.
We start by including the necessary headers and defining a very simple
stream buffer utility class that simplifies encoding and decoding data
between processes:
<code>
#include <mpi.h>
#include <XdmfArray.h>
#include <XdmfHDF.h>
/// Simple memory buffer implementation that keeps track of it's stream pointer.
class Buffer {
private:
std::size_t m_size;
char* m_data;
char* m_put;
char* m_tell;
public:
Buffer( std::size_t size ) :
m_size( size ),
m_data( new char[size] ),
m_put( m_data ),
m_tell( m_data )
{}
~Buffer() {
delete [] m_data;
}
/// copy a contiguous block into the buffer
void put( const void* data, std::size_t size ) {
memcpy( m_put, data, size );
m_put += size;
}
/// put a single value into the buffer
template< typename T >
void put( const T& t ) {
std::size_t size = sizeof( T );
put( &t, size );
}
/// copy a contiguous block of data from the buffer to an already
/// allocated location
void tell( void* out, std::size_t size ) {
memcpy( out, m_tell, size );
m_tell += size;
}
/// Copy a single value into the buffer.
template< typename T >
T tell() {
std::size_t tsize = sizeof( T );
T tmp;
tell( &tmp, tsize );
return tmp;
}
std::size_t size() const {
return m_size;
}
char* pointer() {
return m_data;
}
void reset() {
m_put = m_data;
m_tell = m_data;
}
};
</code>
We haven't yet called on the Xdmf API to do anything, the Buffer class
is just a utility that we will use later.
Now, we write our callback class that will customize the process of
opening, reading, writing, and closing the heavy dataset. Since our
communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback,
XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes
has a single virtual method that takes a pointer to a XdmfHeavyData and
the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close,
XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods.
<code>
/// Callback implements parallel IO by communicating to process 0
class CommunicationCallback :
public XdmfOpenCallback,
public XdmfWriteCallback,
public XdmfCloseCallback,
public XdmfReadCallback
{
private:
int mCommRank;
int mCommSize;
public:
/// Constructor initializes the Number of processors and local process
/// ID.
CommunicationCallback() {
MPI_Comm_size( MPI_COMM_WORLD, &mCommSize );
MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank );
}
/// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going
/// to read or write, so only rank 0 will open the file.
XdmfInt32 DoOpen(
XdmfHeavyData* ds,
XdmfConstString name,
XdmfConstString access )
{
if ( mCommRank == 0 ) {
// Call the actual DoOpen method from XdmfHeavyData
return ds->DoOpen( name, access );
} else {
// Not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0
/// needs to do anything.
XdmfInt32 DoClose( XdmfHeavyData* ds )
{
if ( mCommRank == 0 ) {
// Call the heavy dataset's native close method.
return ds->DoClose();
} else {
// not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfWriteCallback::DoWrite. If the local
/// process ID is 0, then we expect to receive data from everyone
/// else. Otherwise, we send data. Rank 0 does all of the writing.
XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array )
{
// This implementation assumes process 0 has the same data
// size as everyone else
// set up a stream buffer that is large enough to hold the data to
// be sent or received. We require enough space for the rank,
// start, stride, and count for the array plus enough space to hold
// the actual array data.
XdmfInt64 start[1], stride[1], count[1];
XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count );
std::size_t slab_info_size =
sizeof( XdmfInt32 ) // slab rank
+ slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count
Buffer buf( slab_info_size + array->GetCoreLength() );
// If the local process ID is nonzero, pack the buffer and send to
// process 0.
if ( mCommRank != 0 ) {
// copy rank and slab information into the buffer.
buf.put( slab_rank );
for ( int i = 0; i < slab_rank; ++i ) {
buf.put( start[i] );
buf.put( stride[i] );
buf.put( count[i] );
}
// copy the actual data into the buffer.
buf.put( array->GetDataPointer(), array->GetCoreLength() );
// send to rank 0 in the global communicator.
MPI_Send(
buf.pointer(),
buf.size(),
MPI_BYTE,
0,
0,
MPI_COMM_WORLD );
} else {
// Local process ID is 0, so we write local data then receive and
// write remote data.
// first, it's easy to write the local data
ds->DoWrite( array );
int processes_received = 1; // local data for process 0 is written
// loop until the data for all processes has been received.
while ( processes_received < mCommSize ) {
// Fill the buffer with incoming data. We are assuming here
// that all processes contain the same amount of data.
MPI_Recv(
buf.pointer(),
buf.size(),
MPI_BYTE,
MPI_ANY_SOURCE,
0,
MPI_COMM_WORLD,
0 );
processes_received++;
// unpack the buffer
buf.reset(); // reset the stream pointer to the beginning
// we mean rank in the linear algebra sense here
slab_rank = buf.tell< XdmfInt32 >();
// start, stride, and count are next.
for( int i = 0; i < slab_rank; ++i ) {
start[i] = buf.tell< XdmfInt64 >();
stride[i] = buf.tell< XdmfInt64 >();
count[i] = buf.tell< XdmfInt64 >();
}
// select the correct hyper slab in the heavy data set.
ds->SelectHyperSlab( start, stride, count );
// allocate an array to hold the off-core data.
XdmfArray* recv = new XdmfArray;
recv->CopyShape( array );
// place the received data into the array.
buf.tell( recv->GetDataPointer(), recv->GetCoreLength() );
// write the off core data to the dataset by calling the heavy
// data's DoWrite method.
ds->DoWrite( recv );
delete recv;
}
}
return XDMF_SUCCESS;
}
/// Reimplemented from XdmfReadCallback::DoRead. Read the data from a
/// heavy data source into an array only if the local process ID is 0.
/// Otherwise, do nothing.
XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array )
{
if ( mCommRank == 0 ) {
// defer to the actual heavy data implementation of DoRead.
return ds->DoRead( array );
} else {
// return an empty array.
return NULL;
}
}
}; // end of class CommunicationCallback
</code>
One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well.
Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip.
<code>
char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI";
int main( int argc, char* argv[] ) {
// Initialize MPI
MPI_Init( &argc, &argv );
// determine the local process ID
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// Create an HDF dataset to write out to.
XdmfHDF* H5 = new XdmfHDF();
// Attach an instance of the CommunicationCallback class defined above
// to customize opening, writing, and closing the dataset.
CommunicationCallback* cb = new CommunicationCallback;
H5->setOpenCallback( cb );
H5->setWriteCallback( cb );
H5->setCloseCallback(cb );
// Allocate an array of size 25 and fill it with values depending
// on the local process ID (process 0 has 0-24, process 1 has
// 25-49,...)
XdmfArray* MyData = new XdmfArray();
MyData->SetNumberType( XDMF_FLOAT32_TYPE );
MyData->SetNumberOfElements( 25 );
MyData->Generate( rank * 25, rank*25 + 24 );
// Set the dataset's type to the array's type
H5->CopyType( MyData );
// Set up the dimensions of the dataset.
XdmfInt64 dims[1];
dims[0] = 100;
H5->SetShape( 1, dims );
// Set up the hyper slab for the dataset. Each process will select a
// distinct portion of the dataset (process 0 has 0-24, process 1
// 25-49,...)
XdmfInt64 start[1], stride[1], count[1];
start[0] = rank * 25;
stride[0] = 1;
count[0] = 25;
// select the slab in the dataset corresponding to the local process.
H5->SelectHyperSlab( start, stride, count );
// Open the dataset.
H5->Open( kDatasetName, "w" );
// Write the array.
H5->Write( MyData );
// Close the dataset.
H5->Close();
// writing is complete, now we have a quick test to ensure the data
// survives a round trip.
bool failure = false;
// Create a new dataset to read from
XdmfHDF* H5In = new XdmfHDF();
// Use the same callback.
H5In->setReadCallback( cb );
H5In->setOpenCallback( cb );
H5In->setCloseCallback( cb );
// Open the dataset for reading.
H5In->Open( kDatasetName, "r" );
// Read the data into an array.
XdmfArray* result = H5In->Read();
// if the read was successful, make sure the values for all processes
// are in the file.
if ( result ) {
for ( size_t i = 0; i < 100; ++i ) {
float value = result->GetValueAsFloat32( i );
std::cout << i << " " << value << std::endl;
failure = ( value != i );
}
}
MPI_Finalize();
delete H5;
delete cb;
delete MyData;
delete H5In;
delete result;
if ( failure ) {
return -1;
} else {
return 0;
}
};
</code>
Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree.
bd3e519c7b07a12a8752f3146c2ba6515643d79f
69
66
2009-06-26T16:21:42Z
Jerry
2
wikitext
text/x-wiki
(code, example and description provided by Will Dicharry)
=== Controlling the I/O process for XdmfHeavyData ===
The XDMF API provides a customization point to allow the heavy data sets
to be written in a certain manner, depending on the application
environment and independent of the heavy dataset format. New I/O
strategies can be implemented by subclassing the callback classes
defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes.
This method has the advantage of applying a common strategy to any
XdmfHeavyData subclass.
The system works in the following way:
XdmfHeavyData contains the non-virtual methods Open, Close, Read, and
Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite.
XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment.
In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely.
=== Example ===
Suppose we have an MPI environment with 4 processes. Each process
contains part of an array with 100 values numbered 0 to 99; process 0
with items 0-24, process 1 with items 25-49, etc. We would like to
write this data to a single HDF file containing a single array of 100
values, stored in increasing numerical order. To do this, we will
communicate all of the data to process 0 and let process 0 handle the
actual output of the array.
We start by including the necessary headers and defining a very simple
stream buffer utility class that simplifies encoding and decoding data
between processes:
<code>
#include <mpi.h>
#include <XdmfArray.h>
#include <XdmfHDF.h>
/// Simple memory buffer implementation that keeps track of it's stream pointer.
class Buffer {
private:
std::size_t m_size;
char* m_data;
char* m_put;
char* m_tell;
public:
Buffer( std::size_t size ) :
m_size( size ),
m_data( new char[size] ),
m_put( m_data ),
m_tell( m_data )
{}
~Buffer() {
delete [] m_data;
}
/// copy a contiguous block into the buffer
void put( const void* data, std::size_t size ) {
memcpy( m_put, data, size );
m_put += size;
}
/// put a single value into the buffer
template< typename T >
void put( const T& t ) {
std::size_t size = sizeof( T );
put( &t, size );
}
/// copy a contiguous block of data from the buffer to an already
/// allocated location
void tell( void* out, std::size_t size ) {
memcpy( out, m_tell, size );
m_tell += size;
}
/// Copy a single value into the buffer.
template< typename T >
T tell() {
std::size_t tsize = sizeof( T );
T tmp;
tell( &tmp, tsize );
return tmp;
}
std::size_t size() const {
return m_size;
}
char* pointer() {
return m_data;
}
void reset() {
m_put = m_data;
m_tell = m_data;
}
};
</code>
We haven't yet called on the Xdmf API to do anything, the Buffer class
is just a utility that we will use later.
Now, we write our callback class that will customize the process of
opening, reading, writing, and closing the heavy dataset. Since our
communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback,
XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes
has a single virtual method that takes a pointer to a XdmfHeavyData and
the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close,
XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods.
<code>
/// Callback implements parallel IO by communicating to process 0
class CommunicationCallback :
public XdmfOpenCallback,
public XdmfWriteCallback,
public XdmfCloseCallback,
public XdmfReadCallback
{
private:
int mCommRank;
int mCommSize;
public:
/// Constructor initializes the Number of processors and local process
/// ID.
CommunicationCallback() {
MPI_Comm_size( MPI_COMM_WORLD, &mCommSize );
MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank );
}
/// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going
/// to read or write, so only rank 0 will open the file.
XdmfInt32 DoOpen(
XdmfHeavyData* ds,
XdmfConstString name,
XdmfConstString access )
{
if ( mCommRank == 0 ) {
// Call the actual DoOpen method from XdmfHeavyData
return ds->DoOpen( name, access );
} else {
// Not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0
/// needs to do anything.
XdmfInt32 DoClose( XdmfHeavyData* ds )
{
if ( mCommRank == 0 ) {
// Call the heavy dataset's native close method.
return ds->DoClose();
} else {
// not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfWriteCallback::DoWrite. If the local
/// process ID is 0, then we expect to receive data from everyone
/// else. Otherwise, we send data. Rank 0 does all of the writing.
XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array )
{
// This implementation assumes process 0 has the same data
// size as everyone else
// set up a stream buffer that is large enough to hold the data to
// be sent or received. We require enough space for the rank,
// start, stride, and count for the array plus enough space to hold
// the actual array data.
XdmfInt64 start[1], stride[1], count[1];
XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count );
std::size_t slab_info_size =
sizeof( XdmfInt32 ) // slab rank
+ slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count
Buffer buf( slab_info_size + array->GetCoreLength() );
// If the local process ID is nonzero, pack the buffer and send to
// process 0.
if ( mCommRank != 0 ) {
// copy rank and slab information into the buffer.
buf.put( slab_rank );
for ( int i = 0; i < slab_rank; ++i ) {
buf.put( start[i] );
buf.put( stride[i] );
buf.put( count[i] );
}
// copy the actual data into the buffer.
buf.put( array->GetDataPointer(), array->GetCoreLength() );
// send to rank 0 in the global communicator.
MPI_Send(
buf.pointer(),
buf.size(),
MPI_BYTE,
0,
0,
MPI_COMM_WORLD );
} else {
// Local process ID is 0, so we write local data then receive and
// write remote data.
// first, it's easy to write the local data
ds->DoWrite( array );
int processes_received = 1; // local data for process 0 is written
// loop until the data for all processes has been received.
while ( processes_received < mCommSize ) {
// Fill the buffer with incoming data. We are assuming here
// that all processes contain the same amount of data.
MPI_Recv(
buf.pointer(),
buf.size(),
MPI_BYTE,
MPI_ANY_SOURCE,
0,
MPI_COMM_WORLD,
0 );
processes_received++;
// unpack the buffer
buf.reset(); // reset the stream pointer to the beginning
// we mean rank in the linear algebra sense here
slab_rank = buf.tell< XdmfInt32 >();
// start, stride, and count are next.
for( int i = 0; i < slab_rank; ++i ) {
start[i] = buf.tell< XdmfInt64 >();
stride[i] = buf.tell< XdmfInt64 >();
count[i] = buf.tell< XdmfInt64 >();
}
// select the correct hyper slab in the heavy data set.
ds->SelectHyperSlab( start, stride, count );
// allocate an array to hold the off-core data.
XdmfArray* recv = new XdmfArray;
recv->CopyShape( array );
// place the received data into the array.
buf.tell( recv->GetDataPointer(), recv->GetCoreLength() );
// write the off core data to the dataset by calling the heavy
// data's DoWrite method.
ds->DoWrite( recv );
delete recv;
}
}
return XDMF_SUCCESS;
}
/// Reimplemented from XdmfReadCallback::DoRead. Read the data from a
/// heavy data source into an array only if the local process ID is 0.
/// Otherwise, do nothing.
XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array )
{
if ( mCommRank == 0 ) {
// defer to the actual heavy data implementation of DoRead.
return ds->DoRead( array );
} else {
// return an empty array.
return NULL;
}
}
}; // end of class CommunicationCallback
</code>
One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well.
Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip.
<code>
char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI";
int main( int argc, char* argv[] ) {
// Initialize MPI
MPI_Init( &argc, &argv );
// determine the local process ID
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// Create an HDF dataset to write out to.
XdmfHDF* H5 = new XdmfHDF();
// Attach an instance of the CommunicationCallback class defined above
// to customize opening, writing, and closing the dataset.
CommunicationCallback* cb = new CommunicationCallback;
H5->setOpenCallback( cb );
H5->setWriteCallback( cb );
H5->setCloseCallback(cb );
// Allocate an array of size 25 and fill it with values depending
// on the local process ID (process 0 has 0-24, process 1 has
// 25-49,...)
XdmfArray* MyData = new XdmfArray();
MyData->SetNumberType( XDMF_FLOAT32_TYPE );
MyData->SetNumberOfElements( 25 );
MyData->Generate( rank * 25, rank*25 + 24 );
// Set the dataset's type to the array's type
H5->CopyType( MyData );
// Set up the dimensions of the dataset.
XdmfInt64 dims[1];
dims[0] = 100;
H5->SetShape( 1, dims );
// Set up the hyper slab for the dataset. Each process will select a
// distinct portion of the dataset (process 0 has 0-24, process 1
// 25-49,...)
XdmfInt64 start[1], stride[1], count[1];
start[0] = rank * 25;
stride[0] = 1;
count[0] = 25;
// select the slab in the dataset corresponding to the local process.
H5->SelectHyperSlab( start, stride, count );
// Open the dataset.
H5->Open( kDatasetName, "w" );
// Write the array.
H5->Write( MyData );
// Close the dataset.
H5->Close();
// writing is complete, now we have a quick test to ensure the data
// survives a round trip.
bool failure = false;
// Create a new dataset to read from
XdmfHDF* H5In = new XdmfHDF();
// Use the same callback.
H5In->setReadCallback( cb );
H5In->setOpenCallback( cb );
H5In->setCloseCallback( cb );
// Open the dataset for reading.
H5In->Open( kDatasetName, "r" );
// Read the data into an array.
XdmfArray* result = H5In->Read();
// if the read was successful, make sure the values for all processes
// are in the file.
if ( result ) {
for ( size_t i = 0; i < 100; ++i ) {
float value = result->GetValueAsFloat32( i );
std::cout << i << " " << value << std::endl;
failure = ( value != i );
}
}
MPI_Finalize();
delete H5;
delete cb;
delete MyData;
delete H5In;
delete result;
if ( failure ) {
return -1;
} else {
return 0;
}
};
</code>
Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree.
ea4acf12b0ade3117524519bbb92e270521b3fe0
Update proposal 2008 08 17
0
13
70
2009-08-17T14:21:36Z
Dave.demarle
5
New page: In Early 2007, XDMF underwent a substantial revision. What was the original library we now call XDMF1, and the new version is called XDMF2. The move was enabled by a switch to the libxml2 ...
wikitext
text/x-wiki
In Early 2007, XDMF underwent a substantial revision. What was the original library we now call XDMF1, and the new version is called XDMF2. The move was enabled by a switch to the libxml2 xml parsing library. Changes to XDMF included:
1. Replace expat + Xdmf functions with libxml2
2. Support XPath
3. XdmfStructure + XdmfTrasform have been merged into XdmfDataItem
4. DataItem support hierarchical structure
5. Grids support hierarchical structure
6. Added support for Quadratic elements
7. Added support for mixed topologies
8. Added XdmfInformation - Application specific data
9. Added Writing capabilities to Xmdf lib. The state of the DOM is
accurately reflected in the XML
10. All XDMF XML Elements now have an XdmfObject representation
11. Adding DSM
12. Update from hdf 1.6.2 to hdf 1.6.5
At the same time VTK's (and thus ParaView's) interface to XDMF was partially updated to use the new library. That is, vtkXDMFReader was upgraded to recognize the XDMF2's new syntax and directly produce composite data sets instead of multiple outputs, as well as to understand quadratic elements and mixed topologies and produce the corresponding vtk data structures. Meanwhile, vtkXDMFWriter was only upgraded enough to use XDMF2 in a backwards compatibility mode.
Since that time important new features have been added to XDMF2. Although these features exist in the library, not all of them are useable in the vtkXDMFReader, and even fewer are useable in the vtkXDMFReader. The new features include:
temporal support - Jerry and Biddiscombe (Early 2008)
additional cell types - CSimsoft (Early 2008)
ghost levels - Chris Kees (May 2008)
sql - Jerry (?)
compression - Ian Curlington (May 2008)
parallel "strategies" - Will Dicharry (Jun 2008)
in place row/major column reordering - Dominik Szczerba (Jun 2008)
better hdf version independence - Jerry (Jun 2008)
Additionally interest for the following features exists:
units annotations
tabular data (info vis)
out of core row/major reordering
SIL interface
static geometry and topology time varying data optimizations
wildcard specification
Finally, a full suit of web resources for XDMF would be beneficial to the community at large. The most important is comprehensive regression testing. All fundamental data types should be regularly tested so that we get decent coverage of the libraries capabilities, and so that new users have a set of examples to work from. Additional resources such as a bug tracker and online would doxygen documentation are desireable.
WRITER PLAN OF ACTION
Produce hierachical data items when given composite data object inputs
produce full set of data types that reader recognizes
add support for time
parallel efficiency
20458af21292ef248c179771f4d9b112e5cac356
71
70
2009-08-21T15:59:49Z
Dave.demarle
5
update with specifics now that I've actually started working on it
wikitext
text/x-wiki
In Early 2007, XDMF underwent a substantial revision.
What was the original library we now call XDMF1, and the new version is called XDMF2.
The move was enabled by a switch to the libxml2 xml parsing library.
Changes to XDMF included:
1. Replace expat + Xdmf functions with libxml2
2. Support XPath
3. XdmfStructure + XdmfTrasform have been merged into XdmfDataItem
4. DataItem support hierarchical structure
5. Grids support hierarchical structure
6. Added support for Quadratic elements
7. Added support for mixed topologies
8. Added XdmfInformation - Application specific data
9. Added Writing capabilities to Xmdf lib. The state of the DOM is
accurately reflected in the XML
10. All XDMF XML Elements now have an XdmfObject representation
11. Adding DSM
12. Update from hdf 1.6.2 to hdf 1.6.5
At the same time VTK's (and thus ParaView's) interface to XDMF was partially updated to use the new library.
That is, vtkXDMFReader was upgraded to recognize the XDMF2's new syntax (see 4 and 5 above) and directly produce composite data sets instead of multiple outputs.
Meanwhile, vtkXDMFWriter was only upgraded enough to use XDMF2 in a backwards compatibility mode.
The writer does not understand vtkCompositeDataSet types and still expects to be given complex data in the form of multiple inputs - a legacy of the old ParaView multi-part architecture. Additionally the writer is restricted to a few input dataset structures, because it does not make use of XDMF2's support for mixed topologies.
Work is now underway to upgrade the vtk writer, to bring it up to date with the library. See below.
After the initial upgrade to XDMF2, important new features have been added to XDMF.
Although these features exist in the library, not all of them are useable in the vtkXDMFReader, and even fewer are useable in the vtkXDMFWriter.
The new features include:
temporal support - Jerry and Biddiscombe (Early 2008)
additional cell types - CSimsoft (Early 2008)
ghost levels - Chris Kees (May 2008)
sql heavy data - Jerry (?)
compression - Ian Curlington (May 2008)
parallel "strategies" - Will Dicharry (Jun 2008)
in place row/major column reordering - Dominik Szczerba (Jun 2008)
better hdf version independence - Jerry (Jun 2008)
A survey of traffic on the XDMF mailing list shows that there is demand for the following additional features:
unit annotations
tabular data (info vis)
out of core row/major reordering
SIL interface to composite Data
static geometry and topology time varying data optimizations
wildcard specification
Finally, I personally think that a full suite of web resources for XDMF would be beneficial to the community at large.
These would include bug tracker, doxygen documentation, and regression testing.
The most urgent is the need for comprehensive regression testing.
The tests should cover at least the important configurations for XDMF, and the fundamental data types.
The tests would exist to cover the libraries important features, to ensure that they continue to work as developers improve the library, and also to provide a set of working examples for new users.
The configurations of the library that could be tested are the combinations of the following options:
mpi
vtk
system hdf5
system libxml2
system zlib
python
run from install/run from build directory
However only a handful of the combinations need to be tested. For example, it appears that python=ON and MPI=OFF do not compile today.
== Writer ==
Objectives:
produce hierachical data items when given composite data object inputs
produce full set of data types that reader recognizes
add support for time
parallel efficiency
Architecture:
The plan for upgrading the writer is to introduce a new writer class, and to keep the the existing writer functional, until is can be deprecated and removed.
The new writer will be written with these two objectives.
First, it is desireable to minimize in memory copies or raw data, using pointer sharing as much as possible to reduce memory requirements for large data processing.
Second, it is desireable to leave as much work to the XDMF library itself as possible. The existing writer was written before the xdmf2, and thus manually writes out strings to produce XML elements, because XDMF1 did not have support for writing (see 9 above).
The writer then, will be responsible for examining its input vtkDataObject (note, not plural, we will not support writing multiple objects simultaneously), traversing the tree structure if that object is a composite one, and at each node in the tree, making calls the the XDMF library to convert the in memory VTK data structures into XDMF elements, where each element is configured appropriately and given access to the in memory data array addresses.
The initial design will not support parallelism, or temporal support. Once the static and serial code is proven these features will be added. Temporal support will simply involve obtaining the time domain from the input, and then if the input is time varying, beginning the XDMF structure with a temporal collection.
Parallel support can mean several things.
In parallel, each processor may produce its own file, or all might produce a single file either synchronously or in a round robin fasion.
Additionally the data or the xml elements for the file could be shared or transfered between processors.
The optimal strategy depends upon the data and platform, most importantly whether the filesystem is independent, networked or parallel filesystem.
Thus we may support one or more of these parallel options, and the choice will be made after the writer is functioning properly.
1fa3643037b65bed6020417f836559ff8aed8825
72
71
2009-08-24T14:24:44Z
Dave.demarle
5
wikitext
text/x-wiki
In Early 2007, XDMF underwent a substantial revision.
What was the original library we now call XDMF1, and the new version is called XDMF2.
The move was enabled by a switch to the libxml2 xml parsing library.
Changes to XDMF included:
1. Replace expat + Xdmf functions with libxml2
2. Support XPath
3. XdmfStructure + XdmfTrasform have been merged into XdmfDataItem
4. DataItem support hierarchical structure
5. Grids support hierarchical structure
6. Added support for Quadratic elements
7. Added support for mixed topologies
8. Added XdmfInformation - Application specific data
9. Added Writing capabilities to Xmdf lib. The state of the DOM is
accurately reflected in the XML
10. All XDMF XML Elements now have an XdmfObject representation
11. Adding DSM
12. Update from hdf 1.6.2 to hdf 1.6.5
At the same time VTK's (and thus ParaView's) interface to XDMF was partially updated to use the new library.
That is, vtkXDMFReader was upgraded to recognize the XDMF2's new syntax (see 4 and 5 above) and directly produce composite data sets instead of multiple outputs.
Meanwhile, vtkXDMFWriter was only upgraded enough to use XDMF2 in a backwards compatibility mode.
The writer does not understand vtkCompositeDataSet types and still expects to be given complex data in the form of multiple inputs - a legacy of the old ParaView multi-part architecture. Additionally the writer is restricted to a few input dataset structures, because it does not make use of XDMF2's support for mixed topologies.
Work is now underway to upgrade the vtk writer, to bring it up to date with the library. See below.
After the initial upgrade to XDMF2, important new features have been added to XDMF.
Although these features exist in the library, not all of them are useable in the vtkXDMFReader, and even fewer are useable in the vtkXDMFWriter.
The new features include:
temporal support - Jerry and Biddiscombe (Early 2008)
additional cell types - CSimsoft (Early 2008)
ghost levels - Chris Kees (May 2008)
sql heavy data - Jerry (?)
compression - Ian Curlington (May 2008)
parallel "strategies" - Will Dicharry (Jun 2008)
in place row/major column reordering - Dominik Szczerba (Jun 2008)
better hdf version independence - Jerry (Jun 2008)
A survey of traffic on the XDMF mailing list shows that there is demand for the following additional features:
unit annotations
tabular data (info vis)
out of core row/major reordering
SIL interface to composite Data
static geometry and topology time varying data optimizations
wildcard specification
Finally, I personally think that a full suite of web resources for XDMF would be beneficial to the community at large.
These would include bug tracker, doxygen documentation, and regression testing.
The most urgent is the need for comprehensive regression testing.
The tests should cover at least the important configurations for XDMF, and the fundamental data types.
The tests would exist to cover the library's important features, to ensure that they continue to work as developers improve the library, and also to provide a set of working examples for new users.
The configurations of the library that could be tested are the combinations of the following options:
mpi
vtk
system hdf5
system libxml2
system zlib
python
run from install/run from build directory
However only a handful of the combinations need to be tested. The need for testing is corroborated by the fact that as of today it appears that the combination of python=ON and MPI=OFF does not compile.
== Writer ==
Objectives:
produce hierachical data items when given composite data object inputs
produce full set of data types that reader recognizes
add support for time
parallel efficiency
Architecture:
The plan for upgrading the writer is to introduce a new writer class, and to keep the the existing writer functional, until is can be deprecated and removed.
The new writer will be written with these two objectives.
First, it is desirable to minimize in memory copies or raw data, using pointer sharing as much as possible to reduce memory requirements for large data processing.
Second, it is desirable to leave as much work to the XDMF library itself as possible. The existing writer was written before the xdmf2 and manually writes out strings to produce XML elements. Since XDMF2 has support for writing (see 9 above), the new writer should use it directly.
The writer then, will be responsible for examining its input vtkDataObject (note, not plural, we will not support writing multiple objects simultaneously), traversing the tree structure if that object is a composite one, and at each node in the tree, making calls the the XDMF library to convert the in memory VTK data structures into XDMF elements, where each element is configured appropriately and given access to the in memory data array addresses.
The initial design will not support parallelism, or temporal support. Once the static and serial code is proven these features will be added. Temporal support will simply involve obtaining the time domain from the input, and then if the input is time varying, beginning the XDMF structure with a temporal collection.
Parallel support can mean several things.
In parallel, each processor may produce its own file, or all might produce a single file either synchronously or in a round robin fasion.
Additionally the data or the xml elements for the file could be shared or transfered between processors.
The optimal strategy depends upon the data and platform, most importantly whether the filesystem is independent, networked or parallel filesystem.
Thus we may support one or more of these parallel options, and the choice will be made after the writer is functioning properly.
24224fe9ff44a608033320a97c196e241085638d
Xdmf::New()
0
14
75
2010-01-07T15:16:23Z
Jerry
2
New page: After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full fea...
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The '''''existing XML format will most likely stay the same''''' with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly increasing the efficiency of resource management.
'''API changes/additions for sharing and producing data in parallel'''
While reading Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
'''Much more testing, example code, and example datasets'''
a9c64182962c42b909529cd13e9fe17a4d4f8c6f
76
75
2010-01-07T15:31:24Z
Jerry
2
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The '''''existing XML format will most likely stay the same''''' with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly increasing the efficiency of resource management.
'''API changes/additions for sharing and producing data in parallel'''
While reading Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The
current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use
XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea
is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items.
'''Active Grid an/or Attribute'''
Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly
during debugging.
'''Much more testing, example code, and example datasets'''
599ec846a5752182f4cbb490fb4c54b9bb1f3725
77
76
2010-01-07T15:35:32Z
Jerry
2
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The '''''existing XML format will most likely stay the same''''' with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly increasing the efficiency of resource management.
'''API changes/additions for sharing and producing data in parallel'''
While reading Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The
current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use
XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea
is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items.
'''Active Grid an/or Attribute'''
Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly
during debugging.
'''Much more testing, example code, and example datasets'''
CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things
such as parallel I/O, ghost cells, Collections, etc.
1127e8c657670471eeb61b95cdc90354c4a83c87
78
77
2010-01-07T15:37:52Z
Jerry
2
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly increasing the efficiency of resource management.
'''API changes/additions for sharing and producing data in parallel'''
While reading Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The
current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use
XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea
is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items.
'''Active Grid an/or Attribute'''
Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly
during debugging.
'''Much more testing, example code, and example datasets'''
CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things
such as parallel I/O, ghost cells, Collections, etc.
1b14e1864eb866bc0cf94a13db837d6c929b0a94
79
78
2010-01-07T15:41:42Z
Jerry
2
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
Here's a current running list of proposed changes/additions :
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly increasing the efficiency of resource management.
'''API changes/additions for sharing and producing data in parallel'''
While reading Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk SVN Repository at GoogleCode]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The
current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use
XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea
is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items.
'''Active Grid an/or Attribute'''
Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly
during debugging.
'''Much more testing, example code, and example datasets'''
CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things
such as parallel I/O, ghost cells, Collections, etc.
b32c1ecc80d72312dbc2646f50cca3e8e87eec86
80
79
2010-01-07T15:46:21Z
Jerry
2
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
Here's a current running list of proposed changes/additions :
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly enhancing resource management.
'''API changes/additions for sharing and producing data in parallel'''
While accessing simple Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk SVN Repository at GoogleCode]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The
current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use
XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea
is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items.
'''Active Grid an/or Attribute'''
Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly
during debugging.
'''Much more testing, example code, and example datasets'''
CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things
such as parallel I/O, ghost cells, Collections, etc.
ee244829e0c94db6daf3b1a8d1a4dbd250c35d4a
81
80
2010-01-07T15:53:46Z
Jerry
2
wikitext
text/x-wiki
After some discussion with several interested parties, we've decided to
re-work Xdmf a bit. Most of the changes involve the API, particularly
moving to smart pointers and a more full featured and customizable API
for producing Xdmf in parallel.
The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few
additions. So if you're currently producing Xdmf data outside the API
this will have minimal impact. Also if you're just reading Xdmf as a
file format this will have minimal impact as well.
Here's a current running list of proposed changes/additions :
'''Smart Pointers'''
Smart pointers in C++ will help eliminate memory leaks and double free problems.
Most likely the implementation will be intrusive smart pointers with reference counting.
It is expected that moving to smart pointers will have minimal effect on performance while
greatly enhancing resource management.
'''API changes/additions for sharing and producing data in parallel'''
While accessing simple Xdmf is well defined and straight forward in the current API, producing and sharing
the underlying geometric and computed data can become complex (particularly in a parallel computation).
Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.)
it is best to allow the application to determine the proper representation and the most efficient method to
achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible
mechanism.
Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at:
[http://xdm.googlecode.com/svn/trunk SVN Repository at GoogleCode]
'''Remove libxml2 dependencies from base objects - use containers'''
Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to
instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2.
A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and
decouple the generation of the XML using a visitor pattern. This would also allow for various other representations
of the light data as they become necessary.
'''Better Fortran Support'''
Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion.
To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other.
Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least
there should be transposing support with options.
'''Additional Topology Support'''
Additional Topology types
'''Static Geometry, Dynamic Attribute Support'''
If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The
current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use
XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea
is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. DSM applications where
the Heavy Data location stays constant, but the underlying data changes, must be considered.
'''Active Grid an/or Attribute'''
Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly
during debugging.
'''Much more testing, example code, and example datasets'''
CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things
such as parallel I/O, ghost cells, Collections, etc.
85108d2ee3193fa4134b9739344c3a84afc1e668
V3 Road Feature Request
0
15
95
2014-07-25T18:30:16Z
Imikejackson
18
Created page with "== Version 3 Feature Request' == '''Implement AttributeType=Matrix''' I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example o..."
wikitext
text/x-wiki
== Version 3 Feature Request' ==
'''Implement AttributeType=Matrix'''
I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items.
<Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" >
<DataItem Dimensions="3 2" Format="XML" >
0 0
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
<Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" >
<DataItem Dimensions="3 2" Format="XML" >
0 1
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
I would rather do something like this:
<Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix">
<DataItem Dimensions="2 1" Format="XML" >2 1</DataItem>
<DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4">
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</Attribute>
Or something like that.
'''1DCoRectMesh'''
I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data.
7a2c17595ccee711626227dcb2de59720887fb8f
Examples/imagedata
0
16
98
2014-08-19T18:26:04Z
Dave.demarle
5
Created page with "The following will read in an array of floats from h5 with the values associated with the points. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:x..."
wikitext
text/x-wiki
The following will read in an array of floats from h5 with the values associated with the points.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Domain>
<Grid Name="Particle Images" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" Dimensions="400 300 300"/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML">
0 0 0
</DataItem>
<DataItem Name="Spacing" Dimensions="3" NumberType="Float"
Precision="4" Format="XML">
1 1 1
</DataItem>
</Geometry>
<Attribute Name="second 0" AttributeType="Scalar" Center="Node">
<DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The following will read in an array of floats from h5 with the values associated with the cells.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Domain>
<Grid Name="Particle Images" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" Dimensions="401 301 301"/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML">
0 0 0
</DataItem>
<DataItem Name="Spacing" Dimensions="3" NumberType="Float"
Precision="4" Format="XML">
1 1 1
</DataItem>
</Geometry>
<Attribute Name="second 0" AttributeType="Scalar" Center="Cell">
<DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
66a4b28f1cb403370ad45f867904ca30812c61aa
Version 2
0
17
100
2014-08-19T18:45:42Z
Dave.demarle
5
Created page with "version "2" of Xdmf can be found at: git clone git://xdmf.org/Xdmf.git"
wikitext
text/x-wiki
version "2" of Xdmf can be found at:
git clone git://xdmf.org/Xdmf.git
4d8ae04a65e689587ada6abc5ddda0a342af9ab2
Version 1
0
18
101
2014-08-19T18:52:28Z
Dave.demarle
5
Created page with "Version "1" of xdmf can be obtained via: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkou..."
wikitext
text/x-wiki
Version "1" of xdmf can be obtained via:
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf
748054074818604ae71dc7df0b12b7dabe95617a
Version 2
0
17
102
100
2014-08-19T18:54:58Z
Dave.demarle
5
wikitext
text/x-wiki
Version "2" of Xdmf can be found at:
git clone git://xdmf.org/Xdmf.git
The updates to Xdmf in version 2 are summarized in this paper:
[http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792]
13e3dd3dbc769427a4d87800a7a5af214b33c8e3
106
102
2014-08-19T19:03:28Z
Dave.demarle
5
explain the "pv" branch.
wikitext
text/x-wiki
Version "2" of Xdmf can be found at:
git clone git://xdmf.org/Xdmf.git
There are two important branches in the repository, "master" and "pv". The "pv" branch was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system.
The updates to Xdmf in version 2 are summarized in this paper:
[http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792]
6abb690a2f2e5d845cb711c4dcf970238ad1074c
107
106
2014-08-19T19:05:54Z
Dave.demarle
5
wikitext
text/x-wiki
Version "2" of Xdmf can be found at:
git clone git://xdmf.org/Xdmf.git
There are two important branches in the repository, "master" and "pv". The "pv" branch was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system.
The updates to Xdmf in version 2 are summarized in this paper:
[http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792]
and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3]
95345d944cd3ab16c5cc165ea3b3c9407859d800
Version 3
0
19
103
2014-08-19T18:57:57Z
Dave.demarle
5
Created page with "Version "3" of Xdmf can be obtained from: git://public.kitware.com/Xdmf2.git The initial plans for changes that went into version 3 are summarized on: [http://xdmf.org/index...."
wikitext
text/x-wiki
Version "3" of Xdmf can be obtained from:
git://public.kitware.com/Xdmf2.git
The initial plans for changes that went into version 3 are summarized on:
[http://xdmf.org/index.php/Xdmf::New()]
Additionally, this version added support for Graph types.
c50fef82f363ce1ba734ae65b4c7b4c3036d4868
108
103
2014-08-19T19:07:34Z
Dave.demarle
5
wikitext
text/x-wiki
Version "3" of Xdmf can be obtained from:
git://public.kitware.com/Xdmf2.git
The initial plans for changes that went into version 3 are summarized on:
[http://xdmf.org/index.php/Xdmf::New()]
The overall goals included better performance and use of modern and more maintainable C++ programming idioms. This version adds a dependence on boost.
Additionally, this version added support for Graph types and removed support for the SQL back end.
8b6ad6e00d70679bc0bbd0fe8493c18027041f10
Main Page
0
1
104
99
2014-08-19T18:58:55Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Xdmf::New()|'''What's Next''']]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
6e40e509517f6a677f62e72bacea9b09cbd8d9e8
105
104
2014-08-19T18:59:17Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
89c8982e6d48aed577c1edfc966c58d8df1ff99d
109
105
2014-08-19T19:09:51Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Use XDMF from wrapped languages]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
a51f7be4706ea0346ce8856a1bb8140a41728b82
121
109
2014-08-19T19:29:28Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
89c8982e6d48aed577c1edfc966c58d8df1ff99d
125
121
2014-09-02T15:36:46Z
FelipeB
19
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
11473ec14900229f9484ef61ec2a013c844e7859
144
125
2014-11-07T21:07:22Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Write from Fortran|Xdmf3 Fortran API]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
869282ac2f9a5431366c3728fe2550cef3c4d384
145
144
2014-11-07T21:07:46Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Xdmf3 Fortran API|Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
6f37dce2ba7ec34fd340f8aafef86be5b58ce617
Read Xdmf
0
8
110
38
2014-08-19T19:12:14Z
Dave.demarle
5
wikitext
text/x-wiki
== Reading XDMF Data ==
[[Image:TwoHex.jpg]]
The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face.
There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are
all stored directly in the XML file.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf>
<Domain>
<Grid Name="TestGrid">
<Topology Type="Hexahedron" NumberOfElements="2" >
<DataItem Format="XML" DataType="Float"
Dimensions="2 8">
0 1 7 6 3 4 10 9
1 2 8 7 4 5 11 10
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3 3">
0.0 0.0 1.0
1.0 0.0 1.0
3.0 0.0 2.0
0.0 1.0 1.0
1.0 1.0 1.0
3.0 2.0 2.0
0.0 0.0 -1.0
1.0 0.0 -1.0
3.0 0.0 -2.0
0.0 1.0 -1.0
1.0 1.0 -1.0
3.0 2.0 -2.0
</DataItem>
</Geometry>
<Attribute Name="NodeValues" Center="Node">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3" >
100 200 300
300 400 500
300 400 500
500 600 700
</DataItem>
</Attribute>
<Attribute Name="CellValues" Center="Cell">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="2" >
100 200
</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and
retrieving the data values.
<pre style="color: red">Note this code snippet is from version 2 or 1 and needs updating for xdmf3.</pre>
from Xdmf import *
dom = XdmfDOM()
dom.Parse('MyGrid.xmf')
# We now have a tree. Find the one and only Grid element
ge = dom.FindElementByPath('/Xdmf/Domain/Grid')
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
# Read Light Data
grid.UpdateInformation()
# Read Heavy Data which includes Topology and Geometry
grid.Update()
top = grid.GetTopology()
conn = top.GetConnectivity()
print 'Values = ', conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print 'Geo Type = ', geo.GetGeometryTypeAsString(), ' # Points = ', geo.GetNumberOfPoints()
print 'Points = ', points.GetValues()
# for each Attribute, print Light Data and Values
for i in range(grid.GetNumberOfAttributes()) :
attr = grid.GetAttribute(i)
print 'Attribute ', i, ' Name = ', attr.Get('Name')
# Attribute HeavyData is not Updated by default
# there could potentially be many causing huge IO
attr.Update()
vals = attr.GetValues()
print 'Values ', vals.GetValues()
a8bfcce8aed25e197a22acb13f383b6af17d5e57
146
110
2014-11-10T16:43:36Z
Burns
17
wikitext
text/x-wiki
== Reading XDMF Data ==
[[Image:TwoHex.jpg]]
The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face.
There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are
all stored directly in the XML file.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf>
<Domain>
<Grid Name="TestGrid">
<Topology Type="Hexahedron" NumberOfElements="2" >
<DataItem Format="XML" DataType="Float"
Dimensions="2 8">
0 1 7 6 3 4 10 9
1 2 8 7 4 5 11 10
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3 3">
0.0 0.0 1.0
1.0 0.0 1.0
3.0 0.0 2.0
0.0 1.0 1.0
1.0 1.0 1.0
3.0 2.0 2.0
0.0 0.0 -1.0
1.0 0.0 -1.0
3.0 0.0 -2.0
0.0 1.0 -1.0
1.0 1.0 -1.0
3.0 2.0 -2.0
</DataItem>
</Geometry>
<Attribute Name="NodeValues" Center="Node">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3" >
100 200 300
300 400 500
300 400 500
500 600 700
</DataItem>
</Attribute>
<Attribute Name="CellValues" Center="Cell">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="2" >
100 200
</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and
retrieving the data values.
from Xdmf import *
reader = XdmfReader.New()
dom = XdmfReader.read('MyGrid.xmf')
# We now have a tree. Find the one and only Grid element
grid = dom.getUnstruturedGrid(0)
top = grid.GetTopology()
print 'Values = ', top.getValuesString()
# Release values from data when done
top.release()
geo = grid.GetGeometry()
print 'Geo Type = ', geo.getType().getName(), ' # Points = ', geo.getNumberPoints()
print 'Points = ', geo.getValuesString()
geo.release()
# for each Attribute, print Light Data and Values
for i in range(grid.getNumberAttributes()) :
attr = grid.getAttribute(i)
print 'Attribute ', i, ' Name = ', attr.getName()
# Attribute HeavyData is not Updated by default
# there could potentially be many causing huge IO
attr.read()
print 'Values ', attr.getValuesString()
attr.release()
fe43c311473f7bee74fb6e8a351f580c3b0234fe
Write Xdmf
0
9
111
61
2014-08-19T19:14:05Z
Dave.demarle
5
wikitext
text/x-wiki
== Writing Xdmf ==
<pre style="color: red">Note this code snippet is from version 2 or 1 and needs updating for xdmf3.</pre>
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetShapeFromString("10 20 30")
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner.
All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is
built, the XML is blindly copied in and the writing of HeavyData is skipped.
#!/usr/bin/env python
from Xdmf import *
# Example of How to Generate Xdmf
# The Heavy Data for the Attribute is written separately
# Write H5 Data
arr = XdmfArray()
arr.SetNumberType(XDMF_FLOAT64_TYPE)
arr.SetShapeFromString("10 20 30")
arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1)
h5 = XdmfHDF()
h5.CopyType(arr)
h5.CopyShape(arr)
h5.Open('XdmfByHand.h5:/Mydata', 'w')
h5.Write(arr)
h5.Close()
# Use XdmfValuesHDF to generate the appropriate
# Xdmf XML from and existing HDF5 dataset
dv = XdmfValuesHDF()
DataXml = dv.DataItemFromHDF('XdmfByHand.h5:/Mydata')
#
# Now build the tree of objects
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
# Insert the raw XML
attr.SetDataXml(DataXml)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
This results in identical XML with just the name of the HDF5 dataset changed.
~
802535eb3b5811d18d67dacaf4a65dc56e36df5a
114
111
2014-08-19T19:15:51Z
Dave.demarle
5
/* Writing Xdmf */
wikitext
text/x-wiki
== Writing Xdmf ==
<pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre>
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetShapeFromString("10 20 30")
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data
to be written to Xdmf.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner.
All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is
built, the XML is blindly copied in and the writing of HeavyData is skipped.
#!/usr/bin/env python
from Xdmf import *
# Example of How to Generate Xdmf
# The Heavy Data for the Attribute is written separately
# Write H5 Data
arr = XdmfArray()
arr.SetNumberType(XDMF_FLOAT64_TYPE)
arr.SetShapeFromString("10 20 30")
arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1)
h5 = XdmfHDF()
h5.CopyType(arr)
h5.CopyShape(arr)
h5.Open('XdmfByHand.h5:/Mydata', 'w')
h5.Write(arr)
h5.Close()
# Use XdmfValuesHDF to generate the appropriate
# Xdmf XML from and existing HDF5 dataset
dv = XdmfValuesHDF()
DataXml = dv.DataItemFromHDF('XdmfByHand.h5:/Mydata')
#
# Now build the tree of objects
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("SampleLocation")
i.SetValue("4")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
# Insert the raw XML
attr.SetDataXml(DataXml)
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('SMesh.xmf') # write to file
This results in identical XML with just the name of the HDF5 dataset changed.
~
f26ab0d7d54a0567bc85615a11bc4061f94e5acb
147
114
2014-11-10T17:16:38Z
Burns
17
wikitext
text/x-wiki
== Writing Xdmf ==
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted
to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node
from Xdmf import *
root = XdmfDomain.New()
# Information
info = XdmfInformation.New() # Arbitrary Name=Value Facility
info.SetName("SampleLocation")
info.SetValue("4")
root.insert(i) # XML Domain is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Origin X,Y,Z
newGridOrigin = XdmfArray.New()
newGridOrigin.pushBackAsFloat64(1.0)
newGridOrigin.pushBackAsFloat64(2.0)
newGridOrigin.pushBackAsFloat64(3.0)
# Offset X,Y,Z
newBrickSize = XdmfArray.New()
newBrickSize.pushBackAsFloat64(0.1)
newBrickSize.pushBackAsFloat64(0.2)
newBrickSize.pushBackAsFloat64(0.3)
# Points per Dimensio0n
newNumPoints = XdmfArray.New()
newNumPoints.pushBackAsUInt32(10)
newNumPoints.pushBackAsUInt32(20)
newNumPoints.pushBackAsUInt32(30)
# Grid
grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
# Topology and Geometry are set based on the provided arrays
grid.setName("Structured Grid")
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter.Node());
attr.setAttributeType(XdmfAttributeType.Scalar());
# The attribute has the same dims as the Grid
attr.initialize(XdmfArrayType.Float64(), newNumPoints)
# Fill with values however you prefer
# Simply using a loop to fill in this case
for i in range(0, 10 * 20 * 30)
attr.insertAsFloat64(i, 5.0)
grid.insert(attr)
writer = XdmfWriter.New('SMesh.xmf')
root.accept(writer)
Would result in the Light Data XML to be written to the file SMesh.xmf and the Heavy data
to be written to SMesh.h5.
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Information Name="SampleLocation" Value="4"/>
<Domain>
<Grid Name="Structured Grid" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
1 2 3
</DataItem>
<DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML">
0.1 0.2 0.3
</DataItem>
</Geometry>
<Attribute Name="Pressure" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">SMesh.xmf.h5:/Data</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfArrays can be provided a child HeavyDataController that points to a dataset in heavy data. When the XdmfWriter is set to DistributedHeavyData mode it will not read in the data and write it out to a new heavy data location.
#!/usr/bin/env python
from Xdmf import *
# Example of How to Generate Xdmf
# The Heavy Data for the Attribute is written separately
# Write H5 Data
array = XdmfArray.New()
dims = UInt32Vector()
dims.push_back(10)
dims.push_back(20)
dims.push_back(30)
array.initialize(XdmfArrayType.Float64(), dims)
# Simply using a loop to fill in this case
for i in range(0, 10 * 20 * 30)
attr.insertAsFloat64(i, 5.0)
h5writer = XdmfHDF5Writer.New('XdmfByHand.h5')
array.accept(h5writer)
# Retrieve the data set that the writer wrote to
dataset = array.getHeavyDataController().getDataSetPath()
root = XdmfDomain.New()
root.SetDOM(d)
# Information
i = XdmfInformation.New() # Arbitrary Name=Value Facility
i.setName("SampleLocation")
i.setValue("4")
root.insert(i) # XML Domain is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Origin X,Y,Z
newGridOrigin = XdmfArray.New()
newGridOrigin.pushBackAsFloat64(1.0)
newGridOrigin.pushBackAsFloat64(2.0)
newGridOrigin.pushBackAsFloat64(3.0)
# Offset X,Y,Z
newBrickSize = XdmfArray.New()
newBrickSize.pushBackAsFloat64(0.1)
newBrickSize.pushBackAsFloat64(0.2)
newBrickSize.pushBackAsFloat64(0.3)
# Points per Dimensio0n
newNumPoints = XdmfArray.New()
newNumPoints.pushBackAsUInt32(10)
newNumPoints.pushBackAsUInt32(20)
newNumPoints.pushBackAsUInt32(30)
# Grid
grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
# Topology and Geometry are set based on the provided arrays
grid.setName("Structured Grid")
root.insert(g)
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter.Node())
attr.setAttributeType(XdmfAttributeType.Scalar())
# Build a heavy data controller
starts = UInt32Vector()
starts.push_back(0)
starts.push_back(0)
starts.push_back(0)
strides = UInt32Vector()
strides.push_back(1)
strides.push_back(1)
strides.push_back(1)
controller = XdmfHDF5Controller.New('SMesh.h5',
dataset, # Stored from earlier
XdmfArrayType.Float64(),
starts,
strides,
dims,
dims)
writer = XdmfWriter.New('secondSMesh.h5')
writer.setMode(XdmfWriter.DistributedHeavyData)
root.accept(writer)
This results in identical XML with just the name of the HDF5 dataset changed.
26ecfd7412cf299d9152061ee7642130d1e17b70
XDMF API
0
3
112
55
2014-08-19T19:14:41Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<pre style="color: red">Note this code snippet is from version 2 or 1 and needs updating for xdmf3.</pre>
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
6897f36e2ed3f4367016ac487db88edc7f2f3ee9
113
112
2014-08-19T19:15:13Z
Dave.demarle
5
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre>
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
df2f69e2404d3bbe9a8bac1f8567ca0e537a8a2e
127
113
2014-11-07T15:36:29Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre>
'''XDMF API'''
[[Xdmf2 API Archive]]
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
dbbc9a7368ea729c67f58d6e578db3b000ee1dee
130
127
2014-11-07T15:43:23Z
Burns
17
Replaced content with "[[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that ma..."
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
[[Xdmf3 C++ API]]
[[Xdmf3 Python API]]
[[Xdmf3 Fortran API]]
[[Xdmf2 API Archive]]
3b345f2f6f95331759133b19b8788859fd0c5bdd
Write from Fortran
0
10
115
51
2014-08-19T19:16:41Z
Dave.demarle
5
/* Writing Xdmf from Fortran */
wikitext
text/x-wiki
== Writing Xdmf from Fortran ==
<pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre>
Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements
is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider
the following Fortran program which build a grid of Hexahedra with some node and cell centered values :
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Grid of Hexahedron Centered at 0,0,0
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN )
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
INTEGER I, J, K, IDX
REAL*8 X, Y, Z, DX, DY, DZ
C Print *, 'Size = ', IDIM, JDIM, KDIM
PRINT *, 'Initialze Problem'
C XYZ Values of Nodes
C From -1 to 1
DX = 2.0 / ( IDIM - 1 )
DY = 2.0 / ( JDIM - 1 )
DZ = 2.0 / ( KDIM - 1 )
Z = -1.0
DO 112 K= 1, KDIM
Y = -1.0
DO 111 J= 1, JDIM
X = -1.0
DO 110 I= 1, IDIM
XYZ( 1, I, J, K ) = X
XYZ( 2, I, J, K ) = Y
XYZ( 3, I, J, K ) = Z
X = X + DX
110 CONTINUE
Y = Y + DY
111 CONTINUE
Z = Z + DZ
112 CONTINUE
C Connections
IDX = 1
DO 122 K= 0, KDIM - 2
DO 121 J= 0, JDIM - 2
DO 120 I= 1, IDIM - 1
ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1
ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I
ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I
ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I + 1
ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) +
C ( ( J + 1 ) * IDIM ) + I
IDX = IDX + 1
120 CONTINUE
121 CONTINUE
122 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Node Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
INTEGER IDIM, JDIM, KDIM
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
INTEGER I, J, K
REAL*8 X, Y, Z
PRINT *, 'Calculating Node Centered Data'
DO 212, K=1, KDIM
DO 211, J=1, JDIM
DO 210, I=1, IDIM
X = XYZ( 1, I, J, K )
Y = XYZ( 2, I, J, K )
Z = XYZ( 3, I, J, K )
NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z ))
210 CONTINUE
211 CONTINUE
212 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Create a Cell Centered Solution Field
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
INTEGER IDIM, JDIM, KDIM, ITER, KICKER
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
INTEGER I, J, K
PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER
DO 312, K=1, KDIM - 1
DO 311, J=1, JDIM - 1
DO 310, I=1, IDIM - 1
X = XYZ( 1, I, J, K )
CCVALUES( I, J, K ) =
C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) /
C EXP( X / ( 1.0 * ITER ) )
310 CONTINUE
311 CONTINUE
312 CONTINUE
C Waste Time
DO 313 I=1, 1000000
X = 0.1 * ITER / I
Y = SQRT( X * X )
Z = EXP( Y )
313 CONTINUE
RETURN
END
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C Main Program :
C Initialize Grid
C Initialize Node Centered Data
C For Iteration = 1 to 10
C Generate Cell Centered Data
C Done
C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
PROGRAM HexMesh
PARAMETER ( IDIM = 11 )
PARAMETER ( JDIM = 13 )
PARAMETER ( KDIM = 15 )
REAL*8 XYZ
DIMENSION XYZ( 3, IDIM, JDIM, KDIM )
REAL*8 NCVALUES
DIMENSION NCVALUES( IDIM, JDIM, KDIM )
C
REAL*8 CCVALUES
DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 )
C
INTEGER ICONN
DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ))
C
INTEGER ITER, KICKER, NITER, NARG
INTEGER IUNIT
CHARACTER*80 ARGIN
C
NARG = IARGC()
IF( NARG .GE. 1 ) THEN
CALL GETARG( 1, ARGIN )
READ( ARGIN, '(I)') NITER
ELSE
NITER = 10
ENDIF
CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN )
CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES)
C
IUNIT = 14
OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) IDIM * JDIM * KDIM
WRITE ( IUNIT, * ) XYZ
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
WRITE ( IUNIT, * ) ICONN
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' )
REWIND IUNIT
WRITE ( IUNIT, * ) NCVALUES
CLOSE ( IUNIT )
C
IUNIT = 14
OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' )
REWIND IUNIT
C
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now
let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML
via print statements (we could also shove bamboo shoots under our fingernails). A better approach
would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary
Xdmf calls to produce valid Xdmf XML and HDF5 files :
#include <Xdmf.h>
// We want the filenames to be based on the iteration
// and padded with zeros
using std::setw;
using std::setfill;
// This works with g77. Different compilers require different
// name mangling.
'''#define XdmfWrite xdmfwrite_'''
//
// C/C++ expect NULL terminated strings. Here is a conversion subroutine.
char *
DemoConvertFortranString( char *FtnName ) {
static char Name[80];
char *np;
memcpy(Name, FtnName, 79 );
Name[79] = '\0';
np = &Name[78];
while( ( np > Name ) && ( *np <= ' ') ) {
np--;
}
*np = '\0';
return( Name );
}
//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
// really Fortran in this case)
//
extern "C" {
//
void
'''XdmfWrite(''' char *FtnName, int *Iteration,
int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points,
XdmfInt32 *Conns, XdmfFloat64 *NodeData,
XdmfFloat64 *CellData){
char *Name;
char FullName[80];
ostrstream DataName(FullName, 80);
XdmfDOM dom;
XdmfRoot root;
XdmfDomain domain;
XdmfGrid grid;
XdmfTime time;
XdmfTopology *topology;
XdmfGeometry *geometry;
XdmfAttribute nodedata;
XdmfAttribute celldata;
XdmfArray *array;
Name = DemoConvertFortranString( FtnName );
root.SetDOM(&dom);
root.SetVersion(2.0);
root.Build();
// Domain
root.Insert(&domain);
// Grid
grid.SetName("Demonstration Grid");
domain.Insert(&grid);
time.SetTimeType(XDMF_TIME_SINGLE);
time.SetValue(0.001 * *Iteration);
grid.Insert(&time);
// Topology
topology = grid.GetTopology();
topology->SetTopologyType(XDMF_HEX);
topology->SetNumberOfElements(*NumberOfHex);
// Fortran is 1 based while c++ is 0 based so
// Either subtract 1 from all connections or specify a BaseOffset
topology->SetBaseOffset(1);
// If you haven't assigned an XdmfArray, GetConnectivity() will create one.
array = topology->GetConnectivity();
array->SetNumberOfElements(*NumberOfHex * 8);
array->SetValues(0, Conns, *NumberOfHex * 8);
// C++ string hocus pocus.
// We're actually building the string in FullName[] but were using streams.
// the DatasetName will be Demo_00001.h5:/Conns.
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends;
// Where the data will actually be written
array->SetHeavyDataSetName(FullName);
// Geometry
geometry = grid.GetGeometry();
geometry->SetGeometryType(XDMF_GEOMETRY_XYZ);
geometry->SetNumberOfPoints(*NumberOfPoints);
array = geometry->GetPoints();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetValues(0, Points, *NumberOfPoints * 3);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends;
array->SetHeavyDataSetName(FullName);
// Node Data
nodedata.SetName("Node Scalar");
nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE);
nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = nodedata.GetValues();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetNumberOfElements(*NumberOfPoints);
array->SetValues(0, NodeData, *NumberOfPoints);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends;
array->SetHeavyDataSetName(FullName);
// Cell Data
celldata.SetName("Cell Scalar");
celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
array = celldata.GetValues();
array->SetNumberType(XDMF_FLOAT64_TYPE);
array->SetNumberOfElements(*NumberOfHex);
array->SetValues(0, CellData, *NumberOfHex);
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends;
array->SetHeavyDataSetName(FullName);
// Attach and Write
grid.Insert(&nodedata);
grid.Insert(&celldata);
// Build is recursive ... it will be called on all of the child nodes.
// This updates the DOM and writes the HDF5
root.Build();
// Write the XML
DataName.seekp(0);
DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends;
dom.Write(FullName);
}
}
Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()'''
Original :
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
1000 CONTINUE
CLOSE ( IUNIT )
C
END
Modified :
INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )
INPNT = IDIM * JDIM * KDIM
KICKER = NITER
DO 1000 ITER = 1, NITER
CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES)
WRITE ( IUNIT, * ) CCVALUES
'''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)'''
1000 CONTINUE
CLOSE ( IUNIT )
C
END
The program now produces one HDF5 file and one XML file for each iteration. Here is one
of the XML output files :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2">
<Domain>
<Grid Name="Demonstration Grid" GridType="Uniform">
<Topology TopologyType="Hexahedron" NumberOfElements="1680 " BaseOffset="1">
<DataItem Dimensions="13440 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Conns</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Dimensions="6435 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Points</DataItem>
</Geometry>
<Time TimeType="Single" Value="0.004"/>
<Attribute Name="Node Scalar" AttributeType="Scalar" Center="Node">
<DataItem Dimensions="2145 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/NodeData</DataItem>
</Attribute>
<Attribute Name="Cell Scalar" AttributeType="Scalar" Center="Cell">
<DataItem Dimensions="1680 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/CellData</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
The final step would be to group
all of these together so we could animate them over time. Instead of duplicating the XML in another file for
each grid, we can use a little XML magic to pull them together :
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0">
<Domain>
<Grid GridType="Collection" CollectionType="Temporal">
<xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
<xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" />
</Grid>
</Domain>
</Xdmf>
This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists
of the first (in our case, the only) grid in each file. This XML file could be generated programmtically
or by a post processing script.
e32bc46bdc3a44a15f4cdf5e71e5886f92e84806
Read from MySQL
0
11
116
54
2014-08-19T19:17:14Z
Dave.demarle
5
/* Accessing a MySQL DataBase */
wikitext
text/x-wiki
== '''Accessing a MySQL DataBase''' ==
<pre style="color: red">Note SQL support was removed in xdmf 3.</pre>
Partial support for reading data from a MySQL database is available.
MySQL is treated as another HeavyData format like HDF5. Currently
database access is ReadOnly and is accessed by setting the '''Format''' of
the '''DataItem''' in XML equal to '''MySQL'''
<Attribute Name="Cell Centered Values" Center="Cell">
<DataItem Format="MySQL"
Server="localhost"
User="root"
DataBase="MnmiFromout"
Dimensions="3"
NumberType="Float">
<![CDATA[SELECT X FROM Locations WHERE Time < 0.21]]>
</DataItem>
</Attribute>
A Valid SQL statement is placed in the CDATA of the DataItem. When the XdmfDataItem is
updated, an atomic query is made and the result is placed in the XdmfArray of the DataItem.
Putting a "<" (less than) in the CDATA will cause an error in the XML parser. The XML example
above shows how to do this correctly.
The Server, User, and DataBase attributes tell Xdmf how to access MySQL. There is also
a Password attribute. Currently this is just clear text which is a really bad idea. This
will change.
ce1e7dcb75dd0037a9db8695950dacfaf286f53b
Parallel IO with MPI
0
12
117
69
2014-08-19T19:17:41Z
Dave.demarle
5
wikitext
text/x-wiki
<pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre>
(code, example and description provided by Will Dicharry)
=== Controlling the I/O process for XdmfHeavyData ===
The XDMF API provides a customization point to allow the heavy data sets
to be written in a certain manner, depending on the application
environment and independent of the heavy dataset format. New I/O
strategies can be implemented by subclassing the callback classes
defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes.
This method has the advantage of applying a common strategy to any
XdmfHeavyData subclass.
The system works in the following way:
XdmfHeavyData contains the non-virtual methods Open, Close, Read, and
Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite.
XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment.
In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely.
=== Example ===
Suppose we have an MPI environment with 4 processes. Each process
contains part of an array with 100 values numbered 0 to 99; process 0
with items 0-24, process 1 with items 25-49, etc. We would like to
write this data to a single HDF file containing a single array of 100
values, stored in increasing numerical order. To do this, we will
communicate all of the data to process 0 and let process 0 handle the
actual output of the array.
We start by including the necessary headers and defining a very simple
stream buffer utility class that simplifies encoding and decoding data
between processes:
<code>
#include <mpi.h>
#include <XdmfArray.h>
#include <XdmfHDF.h>
/// Simple memory buffer implementation that keeps track of it's stream pointer.
class Buffer {
private:
std::size_t m_size;
char* m_data;
char* m_put;
char* m_tell;
public:
Buffer( std::size_t size ) :
m_size( size ),
m_data( new char[size] ),
m_put( m_data ),
m_tell( m_data )
{}
~Buffer() {
delete [] m_data;
}
/// copy a contiguous block into the buffer
void put( const void* data, std::size_t size ) {
memcpy( m_put, data, size );
m_put += size;
}
/// put a single value into the buffer
template< typename T >
void put( const T& t ) {
std::size_t size = sizeof( T );
put( &t, size );
}
/// copy a contiguous block of data from the buffer to an already
/// allocated location
void tell( void* out, std::size_t size ) {
memcpy( out, m_tell, size );
m_tell += size;
}
/// Copy a single value into the buffer.
template< typename T >
T tell() {
std::size_t tsize = sizeof( T );
T tmp;
tell( &tmp, tsize );
return tmp;
}
std::size_t size() const {
return m_size;
}
char* pointer() {
return m_data;
}
void reset() {
m_put = m_data;
m_tell = m_data;
}
};
</code>
We haven't yet called on the Xdmf API to do anything, the Buffer class
is just a utility that we will use later.
Now, we write our callback class that will customize the process of
opening, reading, writing, and closing the heavy dataset. Since our
communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback,
XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes
has a single virtual method that takes a pointer to a XdmfHeavyData and
the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close,
XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods.
<code>
/// Callback implements parallel IO by communicating to process 0
class CommunicationCallback :
public XdmfOpenCallback,
public XdmfWriteCallback,
public XdmfCloseCallback,
public XdmfReadCallback
{
private:
int mCommRank;
int mCommSize;
public:
/// Constructor initializes the Number of processors and local process
/// ID.
CommunicationCallback() {
MPI_Comm_size( MPI_COMM_WORLD, &mCommSize );
MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank );
}
/// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going
/// to read or write, so only rank 0 will open the file.
XdmfInt32 DoOpen(
XdmfHeavyData* ds,
XdmfConstString name,
XdmfConstString access )
{
if ( mCommRank == 0 ) {
// Call the actual DoOpen method from XdmfHeavyData
return ds->DoOpen( name, access );
} else {
// Not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0
/// needs to do anything.
XdmfInt32 DoClose( XdmfHeavyData* ds )
{
if ( mCommRank == 0 ) {
// Call the heavy dataset's native close method.
return ds->DoClose();
} else {
// not rank 0, nothing to do.
return XDMF_SUCCESS;
}
}
/// Reimplemented from XdmfWriteCallback::DoWrite. If the local
/// process ID is 0, then we expect to receive data from everyone
/// else. Otherwise, we send data. Rank 0 does all of the writing.
XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array )
{
// This implementation assumes process 0 has the same data
// size as everyone else
// set up a stream buffer that is large enough to hold the data to
// be sent or received. We require enough space for the rank,
// start, stride, and count for the array plus enough space to hold
// the actual array data.
XdmfInt64 start[1], stride[1], count[1];
XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count );
std::size_t slab_info_size =
sizeof( XdmfInt32 ) // slab rank
+ slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count
Buffer buf( slab_info_size + array->GetCoreLength() );
// If the local process ID is nonzero, pack the buffer and send to
// process 0.
if ( mCommRank != 0 ) {
// copy rank and slab information into the buffer.
buf.put( slab_rank );
for ( int i = 0; i < slab_rank; ++i ) {
buf.put( start[i] );
buf.put( stride[i] );
buf.put( count[i] );
}
// copy the actual data into the buffer.
buf.put( array->GetDataPointer(), array->GetCoreLength() );
// send to rank 0 in the global communicator.
MPI_Send(
buf.pointer(),
buf.size(),
MPI_BYTE,
0,
0,
MPI_COMM_WORLD );
} else {
// Local process ID is 0, so we write local data then receive and
// write remote data.
// first, it's easy to write the local data
ds->DoWrite( array );
int processes_received = 1; // local data for process 0 is written
// loop until the data for all processes has been received.
while ( processes_received < mCommSize ) {
// Fill the buffer with incoming data. We are assuming here
// that all processes contain the same amount of data.
MPI_Recv(
buf.pointer(),
buf.size(),
MPI_BYTE,
MPI_ANY_SOURCE,
0,
MPI_COMM_WORLD,
0 );
processes_received++;
// unpack the buffer
buf.reset(); // reset the stream pointer to the beginning
// we mean rank in the linear algebra sense here
slab_rank = buf.tell< XdmfInt32 >();
// start, stride, and count are next.
for( int i = 0; i < slab_rank; ++i ) {
start[i] = buf.tell< XdmfInt64 >();
stride[i] = buf.tell< XdmfInt64 >();
count[i] = buf.tell< XdmfInt64 >();
}
// select the correct hyper slab in the heavy data set.
ds->SelectHyperSlab( start, stride, count );
// allocate an array to hold the off-core data.
XdmfArray* recv = new XdmfArray;
recv->CopyShape( array );
// place the received data into the array.
buf.tell( recv->GetDataPointer(), recv->GetCoreLength() );
// write the off core data to the dataset by calling the heavy
// data's DoWrite method.
ds->DoWrite( recv );
delete recv;
}
}
return XDMF_SUCCESS;
}
/// Reimplemented from XdmfReadCallback::DoRead. Read the data from a
/// heavy data source into an array only if the local process ID is 0.
/// Otherwise, do nothing.
XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array )
{
if ( mCommRank == 0 ) {
// defer to the actual heavy data implementation of DoRead.
return ds->DoRead( array );
} else {
// return an empty array.
return NULL;
}
}
}; // end of class CommunicationCallback
</code>
One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well.
Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip.
<code>
char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI";
int main( int argc, char* argv[] ) {
// Initialize MPI
MPI_Init( &argc, &argv );
// determine the local process ID
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
// Create an HDF dataset to write out to.
XdmfHDF* H5 = new XdmfHDF();
// Attach an instance of the CommunicationCallback class defined above
// to customize opening, writing, and closing the dataset.
CommunicationCallback* cb = new CommunicationCallback;
H5->setOpenCallback( cb );
H5->setWriteCallback( cb );
H5->setCloseCallback(cb );
// Allocate an array of size 25 and fill it with values depending
// on the local process ID (process 0 has 0-24, process 1 has
// 25-49,...)
XdmfArray* MyData = new XdmfArray();
MyData->SetNumberType( XDMF_FLOAT32_TYPE );
MyData->SetNumberOfElements( 25 );
MyData->Generate( rank * 25, rank*25 + 24 );
// Set the dataset's type to the array's type
H5->CopyType( MyData );
// Set up the dimensions of the dataset.
XdmfInt64 dims[1];
dims[0] = 100;
H5->SetShape( 1, dims );
// Set up the hyper slab for the dataset. Each process will select a
// distinct portion of the dataset (process 0 has 0-24, process 1
// 25-49,...)
XdmfInt64 start[1], stride[1], count[1];
start[0] = rank * 25;
stride[0] = 1;
count[0] = 25;
// select the slab in the dataset corresponding to the local process.
H5->SelectHyperSlab( start, stride, count );
// Open the dataset.
H5->Open( kDatasetName, "w" );
// Write the array.
H5->Write( MyData );
// Close the dataset.
H5->Close();
// writing is complete, now we have a quick test to ensure the data
// survives a round trip.
bool failure = false;
// Create a new dataset to read from
XdmfHDF* H5In = new XdmfHDF();
// Use the same callback.
H5In->setReadCallback( cb );
H5In->setOpenCallback( cb );
H5In->setCloseCallback( cb );
// Open the dataset for reading.
H5In->Open( kDatasetName, "r" );
// Read the data into an array.
XdmfArray* result = H5In->Read();
// if the read was successful, make sure the values for all processes
// are in the file.
if ( result ) {
for ( size_t i = 0; i < 100; ++i ) {
float value = result->GetValueAsFloat32( i );
std::cout << i << " " << value << std::endl;
failure = ( value != i );
}
}
MPI_Finalize();
delete H5;
delete cb;
delete MyData;
delete H5In;
delete result;
if ( failure ) {
return -1;
} else {
return 0;
}
};
</code>
Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree.
2b22f6ea7c357c6b6dd0540713c9518e01f549e6
148
117
2014-11-10T19:48:18Z
Burns
17
wikitext
text/x-wiki
<pre style="color: red">Note: as of version 1.8.13 hdf5 must be patched as follows to allow for this functionality.</pre>
In the file /hdf5/src/CMakeLists.txt
change
if (NOT HDF5_INSTALL_NO_DEVELOPMENT)
install (
FILES
${H5_PUBLIC_HEADERS}
DESTINATION
${HDF5_INSTALL_INCLUDE_DIR}
COMPONENT
headers
)
endif (NOT HDF5_INSTALL_NO_DEVELOPMENT)
to
if (NOT HDF5_INSTALL_NO_DEVELOPMENT)
install (
FILES
${H5_PUBLIC_HEADERS}
${H5_PRIVATE_HEADERS}
DESTINATION
${HDF5_INSTALL_INCLUDE_DIR}
COMPONENT
headers
)
endif (NOT HDF5_INSTALL_NO_DEVELOPMENT)
===Distributed Shared Memory===
By leveraging the h5fd and hdf5 libraries, Xdmf provides an interface by which a user can set up a dsm server that may be interacted with in a manner similar to hdf5.
As of Xdmf 3.0.0, DSM only allows for the existance of one dataset at a time. This may be worked around by defining a superset and writing datasets to subsections of that superset.
====Initializing DSM====
After starting MPI, the DSM can be started by creating an instance of XdmfHDF5WriterDSM or XdmfHDF5ControllerDSM.
int size, id, dsmSize;
dsmSize = 64;//The total size of the DSM being created
std::string newPath = "dsm";
unsigned int numServersCores = 2;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Init(&argc, &argv);
MPI_Comm_rank(comm, &id);
MPI_Comm_size(comm, &size);
unsigned int dataspaceAllocated = dsmSize/numServersCores;
// Splitting MPICommWorld so that a comm that contains the non-Server cores exists.
MPI_Comm workerComm;
MPI_Group workers, dsmgroup;
MPI_Comm_group(comm, &dsmgroup);
int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
unsigned int index = 0;
for(int i=size-numServersCores ; i <= size-1 ; ++i)
{
ServerIds[index++] = i;
}
MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
int testval = MPI_Comm_create(comm, workers, &workerComm);
cfree(ServerIds);
// The last two cores in the Comm are regulated to manage the DSM.
shared_ptr<XdmfHDF5WriterDSM> exampleWriter =
XdmfHDF5WriterDSM::New(newPath, comm, dataspaceAllocated, size-numServersCores, size-1);
This creates a DSM buffer and manager which must be passed to any new DSM objects in order for those objects to function.
After the user is finished with DSM the manager must be disposed of. Not doing this will result in an error.
if (id == 0)
{
exampleWriter->stopDSM();
}
MPI_Barrier(comm);
//the dsmManager must be deleted or else there will be a segfault
exampleWriter->deleteManager();
MPI_Finalize();
A full example program can be found in the Xdmf source at: Xdmf/core/dsm/tests/Cxx/DSMLoopTest.cpp
c063b01c1ec82d9cbc27f3c2e894fbc75805b07a
149
148
2014-11-10T19:48:48Z
Burns
17
wikitext
text/x-wiki
<pre style="color: red">Note: as of version 1.8.13 hdf5 must be patched as follows to allow for this functionality.</pre>
In the file /hdf5/src/CMakeLists.txt
change
if (NOT HDF5_INSTALL_NO_DEVELOPMENT)
install (
FILES
${H5_PUBLIC_HEADERS}
DESTINATION
${HDF5_INSTALL_INCLUDE_DIR}
COMPONENT
headers
)
endif (NOT HDF5_INSTALL_NO_DEVELOPMENT)
to
if (NOT HDF5_INSTALL_NO_DEVELOPMENT)
install (
FILES
${H5_PUBLIC_HEADERS}
${H5_PRIVATE_HEADERS}
DESTINATION
${HDF5_INSTALL_INCLUDE_DIR}
COMPONENT
headers
)
endif (NOT HDF5_INSTALL_NO_DEVELOPMENT)
===Distributed Shared Memory===
By leveraging the h5fd and hdf5 libraries, Xdmf provides an interface by which a user can set up a dsm server that may be interacted with in a manner similar to hdf5.
As of Xdmf 3.0.0, DSM only allows for the existance of one dataset at a time. This may be worked around by defining a superset and writing datasets to subsections of that superset.
====Initializing DSM====
After starting MPI, the DSM can be started by creating an instance of XdmfHDF5WriterDSM or XdmfHDF5ControllerDSM.
int size, id, dsmSize;
dsmSize = 64;//The total size of the DSM being created
std::string newPath = "dsm";
unsigned int numServersCores = 2;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Init(&argc, &argv);
MPI_Comm_rank(comm, &id);
MPI_Comm_size(comm, &size);
unsigned int dataspaceAllocated = dsmSize/numServersCores;
// Splitting MPICommWorld so that a comm that contains the non-Server cores exists.
MPI_Comm workerComm;
MPI_Group workers, dsmgroup;
MPI_Comm_group(comm, &dsmgroup);
int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
unsigned int index = 0;
for(int i=size-numServersCores ; i <= size-1 ; ++i)
{
ServerIds[index++] = i;
}
MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
int testval = MPI_Comm_create(comm, workers, &workerComm);
cfree(ServerIds);
// The last two cores in the Comm are regulated to manage the DSM.
shared_ptr<XdmfHDF5WriterDSM> exampleWriter =
XdmfHDF5WriterDSM::New(newPath, comm, dataspaceAllocated, size-numServersCores, size-1);
This creates a DSM buffer and manager which must be passed to any new DSM objects in order for those objects to function.
After the user is finished with DSM the manager must be disposed of. Not doing this will result in an error.
if (id == 0)
{
exampleWriter->stopDSM();
}
MPI_Barrier(comm);
//the dsmManager must be deleted or else there will be a segfault
exampleWriter->deleteManager();
MPI_Finalize();
A full example program can be found in the Xdmf source at: Xdmf/core/dsm/tests/Cxx/DSMLoopTest.cpp
b6a7f48b2a7a304e6c3bc9992a6a71d6aa63266f
Get Xdmf original
0
6
118
35
2014-08-19T19:21:11Z
Dave.demarle
5
/* Obtaining and Installing XDMF */
wikitext
text/x-wiki
== '''Obtaining and Installing XDMF''' ==
<pre style="color: red"> These instruction pertain to Xdmf version 1. </pre>
The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin.
CVS Access to the XDMF Source Code Repository
XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS.
Anonymous User Read-Only Access
You can obtain read-only access to the CVS repository as follows.
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login
(respond with password xdmf)
Follow this command by checking out the source code:
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf
This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool.
'''Installation'''
XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com].
Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf <nowiki>(./configure --prefix...)</nowiki> method with CMake.
Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version :
# mkdir MyXdmf
# cd MyXdmf
# cvs <nowiki>-d ...</nowiki> login
# cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code
# mkdir Linux
# cd Linux
# cmake ../Xdmf
CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake.
In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options.
Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files :
* libXdmf.[a so dll] C++ class library for XDMF
* _Xdmf.[so dll] Python interface
* libXdmfTCL.[so dll] Tcl interface
* XdmfFormatExample Executable to write/read XDMF file
The Python interface has been built with the shadow classes. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in <nowiki>.../Xdmf/libsrc/Xdmf.py</nowiki>) somewhere in your Python path.
52d2dd0106c3675113988f1a17e3138543680bfc
119
118
2014-08-19T19:21:57Z
Dave.demarle
5
Dave.demarle moved page [[Get Xdmf]] to [[Get Xdmf original]] without leaving a redirect
wikitext
text/x-wiki
== '''Obtaining and Installing XDMF''' ==
<pre style="color: red"> These instruction pertain to Xdmf version 1. </pre>
The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin.
CVS Access to the XDMF Source Code Repository
XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS.
Anonymous User Read-Only Access
You can obtain read-only access to the CVS repository as follows.
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login
(respond with password xdmf)
Follow this command by checking out the source code:
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf
This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool.
'''Installation'''
XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com].
Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf <nowiki>(./configure --prefix...)</nowiki> method with CMake.
Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version :
# mkdir MyXdmf
# cd MyXdmf
# cvs <nowiki>-d ...</nowiki> login
# cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code
# mkdir Linux
# cd Linux
# cmake ../Xdmf
CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake.
In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options.
Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files :
* libXdmf.[a so dll] C++ class library for XDMF
* _Xdmf.[so dll] Python interface
* libXdmfTCL.[so dll] Tcl interface
* XdmfFormatExample Executable to write/read XDMF file
The Python interface has been built with the shadow classes. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in <nowiki>.../Xdmf/libsrc/Xdmf.py</nowiki>) somewhere in your Python path.
52d2dd0106c3675113988f1a17e3138543680bfc
Get Xdmf
0
20
120
2014-08-19T19:28:31Z
Dave.demarle
5
add updated content
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on boost, zlib and hdf5. You must build those projects before you can build xdmf.
To use Xdmf from Python, Tcl or Java you will also need swig.
To obtain xdmf:
* git clone git://public.kitware.com/Xdmf2.git XDMF
* mkdir build
* cd build
* ccmake ../XDMF
* make
To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake.
Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration.
c11beada65ae87d7c97850ebf6fe5e1ef4edc0cc
123
120
2014-08-19T20:42:37Z
Dave.demarle
5
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on zlib and hdf5 and had a header only dependency on boost. You must obtain and build those projects before you can build xdmf.
To use Xdmf from Python, Tcl or Java you will also need swig.
To obtain xdmf:
* git clone git://public.kitware.com/Xdmf2.git XDMF
* mkdir build
* cd build
* ccmake ../XDMF
* make
To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake.
Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration.
ae03c8e8bbbf57cd42f85f25882c450caa3705f2
Examples/imagedata
0
16
122
98
2014-08-19T19:35:35Z
Dave.demarle
5
wikitext
text/x-wiki
The following will read in an array of floats from h5 with the values associated with the points.
<code format="XML">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Domain>
<Grid Name="Particle Images" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" Dimensions="400 300 300"/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML">
0 0 0
</DataItem>
<DataItem Name="Spacing" Dimensions="3" NumberType="Float" Precision="4" Format="XML">
1 1 1
</DataItem>
</Geometry>
<Attribute Name="second 0" AttributeType="Scalar" Center="Node">
<DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
</code>
The following will read in an array of floats from h5 with the values associated with the cells.
<code format="XML">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Domain>
<Grid Name="Particle Images" GridType="Uniform">
<Topology TopologyType="3DCORECTMesh" Dimensions="401 301 301"/>
<Geometry GeometryType="ORIGIN_DXDYDZ">
<DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML">
0 0 0
</DataItem>
<DataItem Name="Spacing" Dimensions="3" NumberType="Float" Precision="4" Format="XML">
1 1 1
</DataItem>
</Geometry>
<Attribute Name="second 0" AttributeType="Scalar" Center="Cell">
<DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
</code>
9d0dadd993970cf2441bbb3281728956802385a8
V2 To V3
0
21
124
2014-09-02T15:36:29Z
FelipeB
19
Created page with " For more information about the V3 read [[Version 3]] [[V3_Road_Feature_Request|Feature Requests for V3]] TODO list for the transition from V2 to V3: * xdmf.org needs an up..."
wikitext
text/x-wiki
For more information about the V3 read [[Version 3]]
[[V3_Road_Feature_Request|Feature Requests for V3]]
TODO list for the transition from V2 to V3:
* xdmf.org needs an update and currently has documentation for v2. There have been a few changes on what is and is not accepted between versions. For example the "NumberOfElement" tag in the "Topology" is not accepted any more (use "Dimensions" instead). the We are going to be updating it to cover v3 in the near future.
* If we save using the V3 and all the data is stored in the xml (in the case of a 2DCoRectMesh grid with no data) an empty h5 file is generated. Reported in [http://public.kitware.com/Bug/view.php?id=15122]
bcc852d889299269912e1c39b680b12841aeb061
126
124
2014-11-07T15:23:11Z
Burns
17
wikitext
text/x-wiki
For more information about the V3 read [[Version 3]]
[[V3_Road_Feature_Request|Feature Requests for V3]]
TODO list for the transition from V2 to V3:
* xdmf.org needs an update and currently has documentation for v2. There have been a few changes on what is and is not accepted between versions. For example the "NumberOfElement" tag in the "Topology" is not accepted any more (use "Dimensions" instead). the We are going to be updating it to cover v3 in the near future.
* If we save using the V3 and all the data is stored in the xml (in the case of a 2DCoRectMesh grid with no data) an empty h5 file is generated. Reported in [http://public.kitware.com/Bug/view.php?id=15122]
** Will be fixed in the next release.
0beb6e309be3cb2acfc2ec4fa98983340cda676a
150
126
2014-11-20T16:56:28Z
Burns
17
wikitext
text/x-wiki
For more information about the V3 read [[Version 3]]
[[V3_Road_Feature_Request|Feature Requests for V3]]
TODO list for the transition from V2 to V3:
* If we save using the V3 and all the data is stored in the xml (in the case of a 2DCoRectMesh grid with no data) an empty h5 file is generated. Reported in [http://public.kitware.com/Bug/view.php?id=15122]
** Will be fixed in the next release.
f9e7cb144b429904513696c1ab98ebe96b7530e3
Xdmf2 API Archive
0
22
128
2014-11-07T15:36:50Z
Burns
17
Created page with "'''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF li..."
wikitext
text/x-wiki
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
82109b846a11855a28c933c8ee00033aff7e70ce
129
128
2014-11-07T15:37:19Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
'''XDMF API'''
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python.
All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively.
Most examples here are written in Python for clarity.
'''XdmfDOM'''
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode.
The XdmfDOM can parse strings or files :
Status = XdmfDOM.Parse(MyXMLString)
or
Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h.
Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node :
XdmfXmlNode FindElement (
XdmfConstString TagName,
XdmfInt32 Index=0,
XdmfXmlNode Node=NULL,
XdmfInt32 IgnoreInfo=1
)
If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element :
DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults
GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based
By utilizing the XPath functionality of libxml2, the same Grid element can be found by :
GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based
Once the desired node is found, it can be queried and modified :
NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode)
Name = XdmfDOM.GetAttribute(GridNode, "Name")
SubGrid = XdmfDOM.InsertNew(GridNode, "Grid")
Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid")
And finally written back out :
XmlString = XdmfDOM.Serialize(GridNode)
or
Status = XdmfDOM.Write("MyFile.xmf")
'''XdmfElement'''
Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input,
the UpdateInformation() method will initialize the basic structure of the element
from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods.
GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]")
Grid = XdmfGrid() <nowiki>#</nowiki> Create
Grid.SetDOM(DOM)
Grid.SetElement(GridNode)
Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure
Grid.Update() <nowiki>#</nowiki> Read HeavyData
Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods.
GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>)
Is the same as
DOM = Grid.GetDOM()
GridNode = Grid.GetElement()
GridName = DOM.Get(GridNode, "Name")
For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element.
Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility
Info.SetName("Time")
Info.SetValue("0.0123")
Grid = XdmfGrid()
Grid.Set("Name", "My Grid")
Grid.Insert(Info)
Grid.Build()
Results in
<Grid Name="My Grid">
<Information Name="Time" Value="0.0123" />
</Grid>
The Build() method is recursive so that Build() will automatically be called for all child elements.
'''XdmfArray'''
The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>;
XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray;
dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10;
dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20;
dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30;
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->SetNumberType(XDMF_FLOAT64_TYPE)
xyz->SetShape(3, dims); // KDim, JDim, IDim
xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values,
// XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1,
// XdmfInt64 ValuesStride=1)
xyz->SetValues(1, y, total, 3, 1);
xyz->SetValues(2, z, total, 3, 1);
When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples.
from Xdmf import *
def Expression(*args) :
e = ''
for arg in args :
if hasattr(arg, 'GetTagName') :
e += arg.GetTagName() + ' '
else :
e += arg + ' '
return XdmfExpr(e)
if __name__ == '__main__' :
a1 = XdmfArray()
a1.SetNumberType(XDMF_FLOAT32_TYPE)
a1.SetNumberOfElements(20)
a1.Generate(1, 20)
a2 = XdmfArray()
a2.SetNumberType(XDMF_INT32_TYPE)
a2.SetNumberOfElements(5)
a2.Generate(2, 10)
print 'a1 Values = ', a1.GetValues()
print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues()
print 'a2 Values = ', a2.GetValues()
print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues()
print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues()
print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues()
a2.SetNumberType(XDMF_FLOAT32_TYPE)
a2.SetNumberOfElements(20)
a2.Generate(21, 40)
print 'a2 Values = ', a2.GetValues()
print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues()
print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues()
print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues()
print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues()
print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues()
While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra
y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray.
'''XdmfTime'''
When UpdateInformation() gets called for a Grid, an XdmfTime object
is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there
is a <Time> element in the Grid the object is populated. If the
Grid is Non-Uniform (i.e. Collection, Tree), the children are updated
as well. If the parent is
TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the
appropriate value set.
Methods :
XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0)
This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten.
XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax)
this checks to see if the Time is entirely in Min/Max. Since this is
a float comparison, I added an Epsilon member to XdmfTime with default
value = 1e-7. This may be changed via XdmfTime::SetEpsilon()
XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill)
This populates the array with the direct children that are entirely in min/max. For example if the range is
0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL.
'''XdmfHDF'''
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file.
The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use :
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
from Xdmf import *
# Geometry
GeometryArray = XdmfArray()
GeometryArray.SetValues(0, Geometry)
H5 = XdmfHDF()
H5.CopyType(GeometryArray)
H5.CopyShape(GeometryArray)
# Open for Writing. This will truncate the file.
H5.Open('Example1.h5:/Geometry', 'w')
H5.Write(GeometryArray)
H5.Close()
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.SetValues(0, Connectivity)
H5 = XdmfHDF()
H5.CopyType(ConnectivityArray)
H5.CopyShape(ConnectivityArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Connectivity', 'rw')
H5.Write(ConnectivityArray)
H5.Close()
# Values
ValueArray = XdmfArray()
ValueArray.SetValues(0, Values)
H5 = XdmfHDF()
H5.CopyType(ValueArray)
H5.CopyShape(ValueArray)
# Open for Reading and Writing. This will NOT truncate the file.
H5.Open('Example1.h5:/Values', 'rw')
H5.Write(ValueArray)
H5.Close()
For reading, XdmfHDF will allocate an array if none is specified :
Status = H5.Open("Example1.h5:/Values", "rw")
ValueArray = H5.Read()
'''Reading XDMF'''
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values.
dom = XdmfDOM()
dom.Parse("Points.xmf")
ge = dom.FindElementByPath("/Xdmf/Domain/Grid")
grid = XdmfGrid()
grid.SetDOM(dom)
grid.SetElement(ge)
grid.UpdateInformation()
grid.Update()
top = grid.GetTopology()
top.DebugOn()
conn = top.GetConnectivity()
print "Values = ", conn.GetValues()
geo = grid.GetGeometry()
points = geo.GetPoints()
print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints()
print "Points = ", points.GetValues(0, 6)
'''Writing XDMF'''
Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c
an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively.
d = XdmfDOM()
root = XdmfRoot()
root.SetDOM(d)
root.SetVersion(2.2) # Change the Version number because we can
root.Build()
# Information
i = XdmfInformation() # Arbitrary Name=Value Facility
i.SetName("Time")
i.SetValue("0.0123")
root.Insert(i) # XML DOM is used as the keeper of the structure
# Insert() creates an XML node and inserts it under
# the parent
# Domain
dm = XdmfDomain()
root.Insert(dm)
# Grid
g = XdmfGrid()
g.SetName("Structured Grid")
# Topology
t = g.GetTopology()
t.SetTopologyType(XDMF_3DCORECTMESH)
t.GetShapeDesc().SetShapeFromString('10 20 30')
# Geometry
geo = g.GetGeometry()
geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ)
geo.SetOrigin(1, 2, 3)
geo.SetDxDyDz(0.1, 0.2, 0.3)
dm.Insert(g)
# Attribute
attr = XdmfAttribute()
attr.SetName("Pressure")
attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL);
attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR);
p = attr.GetValues()
p.SetNumberOfElements(10 * 20 * 30)
p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1)
# If an array is given a HeavyDataSetName, that is
# where it will be written
p.setHeavyDataSetName('MyData.h5:/Pressure')
g.Insert(attr)
# Update XML and Write Values to DataItems
root.Build() # DataItems > 100 values are heavy
print d.Serialize() # prints to stdout
d.Write('junk.xmf') # write to file
d50586876a68e6b3150117ce287e1ad9b77279a8
Xdmf3 Python API
0
23
131
2014-11-07T16:53:02Z
Burns
17
Created page with "[[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that ..."
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive.
All XDMF Objects are derived from XdmfItem.
===XdmfDomain===
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized.
A Domain can be created inside the code via the New function:
domain = XdmfDomain.New()
A reader can be used to produce a domain from an existing file:
reader = XdmfReader.New()
domain = reader.read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions.
ungrid = domain.getUnstructuredGrid(0)
The same grid can also be fetched by name.
ungrid = domain.getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>)
Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children.
originalName = ungrid.getName()
ungrid.setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>)
When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor.
writer = XdmfWriter.New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>)
domain.accept(writer)
===XdmfArray===
The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
x = [1, 2, 3, ..]
y = [1, 2, 3, ..]
z = [1, 2, 3, ..]
dims = UInt32Vector()
dims.push_back(10)
dims.push_back(20)
dims.push_back(30)
total = 10 * 20 * 30
xyz = XdmfArray.New()
xyz.initialize(XdmfArrayType.Float64(), dims); // KDim, JDim, IDim
xyz.insertAsFloat64(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values,
// unsigned int NumberOfValues, unsigned int ArrayStride=1,
// unsigned int ValuesStride=1)
xyz.insertAsFloat64(1, y, 0, total, 3, 1);
xyz.insertAsFloat64(2, z, 0, total, 3, 1);
===XdmfTime===
When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps.
time = XdmfTime.New(5.0)
ungrid.setTime(time)
===XdmfHDF===
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include:
* Default
* Overwrite
* Append
* Hyperslab
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
heavywriter = XdmfHDF5Writer.New(<nowiki>"example.h5"</nowiki>)
# Geometry
GeometryArray = XdmfArray()
GeometryArray.insertAsFloat64(0, Geometry)
GeometryArray.accept(heavywriter)
# Coneectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.insertAsFloat64(0, Connectivity)
ConnectivityArray.accept(heavywriter)
# Values
ValueArray = XdmfArray()
ValueArray.insertAsFloat64(0, Values)
ValueArray.accept(heavywriter)
When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array.
newPath = "File path to hdf5 file goes here"
newSetPath = "path to the set goes here"
readType = XdmfArrayType.Int32()
#Xdmf provides wrappers for C++ types
#in this case std::vector<unsigned int>
readStarts = UInt32Vector()
#Three dimensions, all starting at index 0
readStarts.push_back(0)
readStarts.push_back(0)
readStarts.push_back(0)
readStrides = UInt32Vector()
#Three dimensions, no skipping between index
readStrides.push_back(1)
readStrides.push_back(1)
readStrides.push_back(1)
readCounts = UInt32Vector()
#Three dimensions, reading 10 values from each
readCounts.push_back(10)
readCounts.push_back(10)
readCounts.push_back(10)
readDataSize = UInt32Vector()
#three dimensins, each with 20 maximum values
readDataSize.push_back(20)
readDataSize.push_back(20)
readDataSize.push_back(20)
controller = XdmfHDF5Controller.New(
newPath,
newSetPath,
readType,
readStarts,
readStrides,
readCounts,
readDataSize)
array.insert(controller)
array.read()
===Reading XDMF===
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a Python example to read and print values.
reader = XdmfReader.New()
domain = reader.read(<nowiki>"Points.xmf"</nowiki>)
grid = domain.getUnstructuredGrid(0)
topology = grid.getTopology()
print "Values = ", topology.getValuesString()
geometry = grid.getGeometry()
print "Geo Type = ", geo.getType().getName(), " # Points = ", geometry.getNumberOfPoints()
print "Points = ", geometry.getValuesString()
===Writing XDMF===
Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup.
root = XdmfDomain.New()
# Information
i = XdmfInformation.New() # Arbitrary Name=Value Facility
i.setName("Time")
i.setValue("0.0123")
root.insert(i) # XdmfDomain is the root of the tree
# insert adds the information we just created as a leaf
# Dimensions
dimensions = XdmfArray.New()
dimensions.pushBackAsUInt32(10)
dimensions.pushBackAsUInt32(20)
dimensions.pushBackAsUInt32(30)
# Origin
origin = XdmfArray.New()
origin.pushBackAsUInt32(1)
origin.pushBackAsUInt32(2)
origin.pushBackAsUInt32(3)
# Brick Size
brick = XdmfArray.New()
brick.pushBackAsUInt32(1)
brick.pushBackAsUInt32(2)
brick.pushBackAsUInt32(3)
# Grid
g = XdmfRegularGrid.New(brick, dimensions, origin)
g.setName("Structured Grid")
root.Insert(g)
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter::Cell());
attr.setAttributeType(XdmfAttributeType::Scalar());
attr.initializeAsFloat64(10 * 20 * 30)
pressureVals = {0, 1, 2, 3, 4, 5, ...}
attr.insert(0, pressureVals)
# The heavy data set name is determined by the writer if not set
g.insert(attr)
# Generate a writer
writer = XdmfWriter.New(<nowiki>"output.xmf"</nowiki>)
domain.accept(writer)
e6fbc040e98eefc18be96bb133e242ce8ebc0a91
132
131
2014-11-07T16:55:38Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive.
All XDMF Objects are derived from XdmfItem.
===XdmfDomain===
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized.
A Domain can be created inside the code via the New function:
domain = XdmfDomain.New()
A reader can be used to produce a domain from an existing file:
reader = XdmfReader.New()
domain = reader.read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions.
ungrid = domain.getUnstructuredGrid(0)
The same grid can also be fetched by name.
ungrid = domain.getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>)
Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children.
originalName = ungrid.getName()
ungrid.setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>)
When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor.
writer = XdmfWriter.New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>)
domain.accept(writer)
===XdmfArray===
The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
x = [1, 2, 3, ..]
y = [1, 2, 3, ..]
z = [1, 2, 3, ..]
dims = UInt32Vector()
dims.push_back(10)
dims.push_back(20)
dims.push_back(30)
total = 10 * 20 * 30
xyz = XdmfArray.New()
xyz.initialize(XdmfArrayType.Float64(), dims); // KDim, JDim, IDim
xyz.insertAsFloat64(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values,
// unsigned int NumberOfValues, unsigned int ArrayStride=1,
// unsigned int ValuesStride=1)
xyz.insertAsFloat64(1, y, 0, total, 3, 1);
xyz.insertAsFloat64(2, z, 0, total, 3, 1);
===XdmfTime===
When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps.
time = XdmfTime.New(5.0)
ungrid.setTime(time)
===XdmfHDF===
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include:
* Default
* Overwrite
* Append
* Hyperslab
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
heavywriter = XdmfHDF5Writer.New(<nowiki>"example.h5"</nowiki>)
# Geometry
GeometryArray = XdmfArray()
GeometryArray.insertAsFloat64(0, Geometry)
GeometryArray.accept(heavywriter)
# Connectivity
ConnectivityArray = XdmfArray()
ConnectivityArray.insertAsFloat64(0, Connectivity)
ConnectivityArray.accept(heavywriter)
# Values
ValueArray = XdmfArray()
ValueArray.insertAsFloat64(0, Values)
ValueArray.accept(heavywriter)
When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array.
newPath = "File path to hdf5 file goes here"
newSetPath = "path to the set goes here"
readType = XdmfArrayType.Int32()
#Xdmf provides wrappers for C++ types
#in this case std::vector<unsigned int>
readStarts = UInt32Vector()
#Three dimensions, all starting at index 0
readStarts.push_back(0)
readStarts.push_back(0)
readStarts.push_back(0)
readStrides = UInt32Vector()
#Three dimensions, no skipping between index
readStrides.push_back(1)
readStrides.push_back(1)
readStrides.push_back(1)
readCounts = UInt32Vector()
#Three dimensions, reading 10 values from each
readCounts.push_back(10)
readCounts.push_back(10)
readCounts.push_back(10)
readDataSize = UInt32Vector()
#three dimensins, each with 20 maximum values
readDataSize.push_back(20)
readDataSize.push_back(20)
readDataSize.push_back(20)
controller = XdmfHDF5Controller.New(
newPath,
newSetPath,
readType,
readStarts,
readStrides,
readCounts,
readDataSize)
array.insert(controller)
array.read()
===Reading XDMF===
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a Python example to read and print values.
reader = XdmfReader.New()
domain = reader.read(<nowiki>"Points.xmf"</nowiki>)
grid = domain.getUnstructuredGrid(0)
topology = grid.getTopology()
print "Values = ", topology.getValuesString()
geometry = grid.getGeometry()
print "Geo Type = ", geo.getType().getName(), " # Points = ", geometry.getNumberOfPoints()
print "Points = ", geometry.getValuesString()
===Writing XDMF===
Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup.
root = XdmfDomain.New()
# Information
i = XdmfInformation.New() # Arbitrary Name=Value Facility
i.setName("Time")
i.setValue("0.0123")
root.insert(i) # XdmfDomain is the root of the tree
# insert adds the information we just created as a leaf
# Dimensions
dimensions = XdmfArray.New()
dimensions.pushBackAsUInt32(10)
dimensions.pushBackAsUInt32(20)
dimensions.pushBackAsUInt32(30)
# Origin
origin = XdmfArray.New()
origin.pushBackAsUInt32(1)
origin.pushBackAsUInt32(2)
origin.pushBackAsUInt32(3)
# Brick Size
brick = XdmfArray.New()
brick.pushBackAsUInt32(1)
brick.pushBackAsUInt32(2)
brick.pushBackAsUInt32(3)
# Grid
g = XdmfRegularGrid.New(brick, dimensions, origin)
g.setName("Structured Grid")
root.Insert(g)
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter::Cell());
attr.setAttributeType(XdmfAttributeType::Scalar());
attr.initializeAsFloat64(10 * 20 * 30)
pressureVals = {0, 1, 2, 3, 4, 5, ...}
attr.insert(0, pressureVals)
# The heavy data set name is determined by the writer if not set
g.insert(attr)
# Generate a writer
writer = XdmfWriter.New(<nowiki>"output.xmf"</nowiki>)
domain.accept(writer)
0518535279281a7e79b7edd02a8d8903fc257f24
133
132
2014-11-07T17:09:52Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive.
All XDMF Objects are derived from XdmfItem.
===XdmfDomain===
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized.
A Domain can be created inside the code via the New function:
domain = XdmfDomain.New()
A reader can be used to produce a domain from an existing file:
reader = XdmfReader.New()
domain = reader.read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)
Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions.
ungrid = domain.getUnstructuredGrid(0)
The same grid can also be fetched by name.
ungrid = domain.getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>)
Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children.
originalName = ungrid.getName()
ungrid.setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>)
When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor.
writer = XdmfWriter.New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>)
domain.accept(writer)
===XdmfArray===
The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
x = [1, 2, 3, ..]
y = [1, 2, 3, ..]
z = [1, 2, 3, ..]
dims = UInt32Vector()
dims.push_back(10)
dims.push_back(20)
dims.push_back(30)
total = 10 * 20 * 30
xyz = XdmfArray.New()
xyz.initialize(XdmfArrayType.Float64(), dims); // KDim, JDim, IDim
xyz.insertAsFloat64(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values,
// unsigned int NumberOfValues, unsigned int ArrayStride=1,
// unsigned int ValuesStride=1)
xyz.insertAsFloat64(1, y, 0, total, 3, 1);
xyz.insertAsFloat64(2, z, 0, total, 3, 1);
===XdmfTime===
When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps.
time = XdmfTime.New(5.0)
ungrid.setTime(time)
===XdmfHDF===
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include:
* Default
* Overwrite
* Append
* Hyperslab
from Xdmf import <nowiki>*</nowiki>
Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75
Connectivity = "3 2 5 1 .
Values = "100 200 300 ..
heavywriter = XdmfHDF5Writer.New(<nowiki>"example.h5"</nowiki>)
# Geometry
GeometryArray = XdmfGeometry.New()
GeometryArray.insertAsFloat64(0, Geometry)
GeometryArray.accept(heavywriter)
# Connectivity
ConnectivityArray = XdmfTopology.New()
ConnectivityArray.insertAsFloat64(0, Connectivity)
ConnectivityArray.accept(heavywriter)
# Values
ValueArray = XdmfArray.New()
ValueArray.insertAsFloat64(0, Values)
ValueArray.accept(heavywriter)
When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array.
newPath = "File path to hdf5 file goes here"
newSetPath = "path to the set goes here"
readType = XdmfArrayType.Int32()
#Xdmf provides wrappers for C++ types
#in this case std::vector<unsigned int>
readStarts = UInt32Vector()
#Three dimensions, all starting at index 0
readStarts.push_back(0)
readStarts.push_back(0)
readStarts.push_back(0)
readStrides = UInt32Vector()
#Three dimensions, no skipping between index
readStrides.push_back(1)
readStrides.push_back(1)
readStrides.push_back(1)
readCounts = UInt32Vector()
#Three dimensions, reading 10 values from each
readCounts.push_back(10)
readCounts.push_back(10)
readCounts.push_back(10)
readDataSize = UInt32Vector()
#three dimensins, each with 20 maximum values
readDataSize.push_back(20)
readDataSize.push_back(20)
readDataSize.push_back(20)
controller = XdmfHDF5Controller.New(
newPath,
newSetPath,
readType,
readStarts,
readStrides,
readCounts,
readDataSize)
array.insert(controller)
array.read()
===Reading XDMF===
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a Python example to read and print values.
reader = XdmfReader.New()
domain = reader.read(<nowiki>"Points.xmf"</nowiki>)
grid = domain.getUnstructuredGrid(0)
topology = grid.getTopology()
print "Values = ", topology.getValuesString()
geometry = grid.getGeometry()
print "Geo Type = ", geo.getType().getName(), " # Points = ", geometry.getNumberOfPoints()
print "Points = ", geometry.getValuesString()
===Writing XDMF===
Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup.
root = XdmfDomain.New()
# Information
i = XdmfInformation.New() # Arbitrary Name=Value Facility
i.setName("Time")
i.setValue("0.0123")
root.insert(i) # XdmfDomain is the root of the tree
# insert adds the information we just created as a leaf
# Dimensions
dimensions = XdmfArray.New()
dimensions.pushBackAsUInt32(10)
dimensions.pushBackAsUInt32(20)
dimensions.pushBackAsUInt32(30)
# Origin
origin = XdmfArray.New()
origin.pushBackAsUInt32(1)
origin.pushBackAsUInt32(2)
origin.pushBackAsUInt32(3)
# Brick Size
brick = XdmfArray.New()
brick.pushBackAsUInt32(1)
brick.pushBackAsUInt32(2)
brick.pushBackAsUInt32(3)
# Grid
g = XdmfRegularGrid.New(brick, dimensions, origin)
g.setName("Structured Grid")
root.Insert(g)
# Attribute
attr = XdmfAttribute.New()
attr.setName("Pressure")
attr.setAttributeCenter(XdmfAttributeCenter::Cell());
attr.setAttributeType(XdmfAttributeType::Scalar());
attr.initializeAsFloat64(10 * 20 * 30)
pressureVals = {0, 1, 2, 3, 4, 5, ...}
attr.insert(0, pressureVals)
# The heavy data set name is determined by the writer if not set
g.insert(attr)
# Generate a writer
writer = XdmfWriter.New(<nowiki>"output.xmf"</nowiki>)
domain.accept(writer)
369bcef7b7c9fd349a6a17e5ad54aa118654144f
Xdmf3 C++ API
0
24
134
2014-11-07T17:49:16Z
Burns
17
Created page with "[[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that..."
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive.
All XDMF Objects are derived from XdmfItem.
===XdmfDomain===
To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized.
A Domain can be created inside the code via the New function:
shared_ptr<nowiki><XdmfDomain></nowiki> domain = XdmfDomain::New();
A reader can be used to produce a domain from an existing file:
shared_ptr<nowiki><XdmfReader></nowiki> reader = XdmfReader::New();
shared_ptr<nowiki><XdmfDomain></nowiki> domain =
shared_dynamic_cast<nowiki><XdmfDomain></nowiki>(reader->read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>));
Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions.
shared_ptr<nowiki><XdmfUnstructuredGrid></nowiki> ungrid = domain->getUnstructuredGrid(0);
The same grid can also be fetched by name.
shared_ptr<nowiki><XdmfUnstructuredGrid></nowiki> ungrid = domain->getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>);
Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children.
std::string originalName = ungrid->getName();
ungrid->setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>);
When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor.
shared_ptr<nowiki><XdmfWriter></nowiki> writer = XdmfWriter::New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>);
domain->accept(writer);
===XdmfArray===
The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables:
float *x, *y, *z;
unsigned int total;
std::vector<unsigned int> dims;
dims.push_back(10);
dims.push_back(20);
dims.push_back(30);
shared_ptr<nowiki><XdmfArray></nowiki> xyz = XdmfArray::New();
total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30;
xyz->initialize(XdmfArrayType::Float64(), dims); // KDim, JDim, IDim
xyz->insert(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values,
// unsigned int NumberOfValues, unsigned int ArrayStride=1,
// unsigned int ValuesStride=1)
xyz->insert(1, y, 0, total, 3, 1);
xyz->insert(2, z, 0, total, 3, 1);
===XdmfTime===
When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps.
shared_ptr<nowiki><XdmfTime></nowiki> time = XdmfTime::New(5.0);
ungrid->setTime(time);
===XdmfHDF===
In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include:
* Default
* Overwrite
* Append
* Hyperslab
double * Geometry = [-1.75, -1.25, 0, -1.25, -1.25, 0, -0.75, ..];
unsigned int * Connectivity = [3, 2, 5, 1, ..];
int Values = [100, 200, 300, ..];
shared_ptr<nowiki><XdmfHDF5Writer></nowiki> heavywriter = XdmfHDF5Writer->New(<nowiki>"example.h5"</nowiki>);
// Geometry
shared_ptr<nowiki><XdmfGeometry></nowiki> GeometryArray = XdmfGeometry::New();
GeometryArray->insert(0, Geometry, geometryNumValues);
GeometryArray->accept(heavywriter);
// Coneectivity
shared_ptr<nowiki><XdmfTopology></nowiki> ConnectivityArray = XdmfTopology::New();
ConnectivityArray->insert(0, Connectivity, connectivityNumValues);
ConnectivityArray->accept(heavywriter);
// Values
shared_ptr<nowiki><XdmfArray></nowiki> ValueArray = XdmfArray::New();
ValueArray->insert(0, Values, numValues);
ValueArray->accept(heavywriter);
When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array.
std::string newPath = "File path to hdf5 file goes here";
std::string newSetPath = "path to the set goes here";
shared_ptr<nowiki><const XdmfArrayType></nowiki> readType = XdmfArrayType::Int32();
std::vector<nowiki><unsigned int></nowiki> readStarts;
//Three dimensions, all starting at index 0
readStarts.push_back(0);
readStarts.push_back(0);
readStarts.push_back(0);
std::vector<nowiki><unsigned int></nowiki> readStrides;
//Three dimensions, no skipping between index
readStrides.push_back(1);
readStrides.push_back(1);
readStrides.push_back(1);
std::vector<nowiki><unsigned int></nowiki> readCounts;
//Three dimensions, reading 10 values from each
readCounts.push_back(10);
readCounts.push_back(10);
readCounts.push_back(10);
std::vector<nowiki><unsigned int></nowiki> readDataSize;
//Three dimensins, each with 20 maximum values
readDataSize.push_back(20);
readDataSize.push_back(20);
readDataSize.push_back(20);
shared_ptr<nowiki><XdmfHDF5Controller></nowiki> controller = XdmfHDF5Controller::New(
newPath,
newSetPath,
readType,
readStarts,
readStrides,
readCounts,
readDataSize);
array->insert(controller);
array->read();
===Reading XDMF===
Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a C++ example to read and print values.
shared_ptr<nowiki><XdmfReader></nowiki> reader = XdmfReader->New();
shared_ptr<nowiki><XdmfDomain></nowiki> domain =
shared_dynamic_cast<nowiki><XdmfDomain></nowiki>(reader->.read(<nowiki>"Points.xmf"</nowiki>));
shared_ptr<nowiki><XdmfUnstructuredGrid></nowiki> grid = domain->getUnstructuredGrid(0);
shared_ptr<nowiki><XdmfTopology></nowiki> topology = grid->getTopology();
printf("Values = %s\n", topology->getValuesString().c_str());
shared_ptr<nowiki><XdmfGeometry></nowiki> geometry = grid->getGeometry();
printf("Geo Type = %s # Points = %u\n", geometry->getType()->getName().c_str(), geometry->getNumberOfPoints());
printf("Points = %s\n", geometry->getValuesString());
===Writing XDMF===
Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup.
shared_ptr<nowiki><XdmfDomain></nowiki> root = XdmfDomain::New();
# Information
shared_ptr<nowiki><XdmfInformation></nowiki> i = XdmfInformation::New(); # Arbitrary Name=Value Facility
i->setName("Time");
i->setValue(0.0123);
root->insert(i); # XdmfDomain is the root of the tree
# insert adds the information we just created as a leaf
# Dimensions
shared_ptr<nowiki><XdmfArray></nowiki> dimensions = XdmfArray::New();
dimensions->pushBack((unsigned int)10);
dimensions->pushBack((unsigned int)20);
dimensions->pushBack((unsigned int)30);
# Origin
shared_ptr<nowiki><XdmfArray></nowiki> origin = XdmfArray::New();
origin->pushBack((unsigned int)1);
origin->pushBack((unsigned int)2);
origin->pushBack((unsigned int)3);
# Brick Size
shared_ptr<nowiki><XdmfArray></nowiki> brick = XdmfArray::New();
brick->pushBack((unsigned int)1);
brick->pushBack((unsigned int)2);
brick->pushBack((unsigned int)3);
# Grid
shared_ptr<nowiki><XdmfRegularGrid></nowiki> g = XdmfRegularGrid::New(brick, dimensions, origin);
g->setName("Structured Grid");
root->insert(g);
# Attribute
shared_ptr<nowiki><XdmfAttribute></nowiki> attr = XdmfAttribute::New();
attr->setName("Pressure");
attr->setAttributeCenter(XdmfAttributeCenter::Cell());
attr->setAttributeType(XdmfAttributeType::Scalar());
attr->initialize(XdmfArrayType::Float64(), 10 * 20 * 30);
double * pressureVals = [0, 1, 2, 3, 4, 5, ...];
attr->insert(0, pressureVals, numPressureVals);
# The heavy data set name is determined by the writer if not set
g->insert(attr);
# Generate a writer
shared_ptr<nowiki><XdmfWriter></nowiki> writer = XdmfWriter::New(<nowiki>"output.xmf"</nowiki>);
domain->accept(writer)
e2c545132bd712573af50374d355a805a8add5e5
Xdmf3 Fortran API
0
25
135
2014-11-07T18:44:32Z
Burns
17
Created page with "[[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a..."
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root.
After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain.
CALL XDMFINIT(obj, filename)
The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root.
===XdmfGridCollections===
After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to.
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Add a Grid Collection to the tree:
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Another Grid Collection is added:
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION.
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Remove a Grid Collection from the top of the stack:
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Returning a Grid Collection to the stack adds it to the top:
! Returning the Grid Collection contained in the domain at position 0 to the stack
CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added.
Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls.
CALL XDMFINIT(obj, filename)
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Xdmf Tree:
Domain
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Xdmf Tree
Domain
|->Grid Collection
|->Grid Collection2
! Removing the grid Collection from the top of the stack.
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
! Adding a Grid Collection named "Grid Collection3"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
ed399955b666d38ddb9e9f74c89094b93cd882e9
136
135
2014-11-07T19:15:06Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root.
After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain.
CALL XDMFINIT(obj, filename)
The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root.
===XdmfGridCollections===
After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to.
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Add a Grid Collection to the tree:
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Another Grid Collection is added:
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION.
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Remove a Grid Collection from the top of the stack:
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Returning a Grid Collection to the stack adds it to the top:
! Returning the Grid Collection contained in the domain at position 0 to the stack
CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added.
Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls.
CALL XDMFINIT(obj, filename)
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Xdmf Tree:
Domain
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Xdmf Tree
Domain
|->Grid Collection
|->Grid Collection2
! Removing the grid Collection from the top of the stack.
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
! Adding a Grid Collection named "Grid Collection3"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within.
{| class="wikitable"
!Object
!Working Arrays Cleared
|-
|GridCollection
|Attributes, Information, Maps, Sets
|-
|Grid
|Attributes, Information, Maps, Sets
|-
|Attribute
|Information
|-
|Information
|None
|-
|Map
|none
|-
|Set
|Attributes, Information
|}
After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called.
! Adding an attribute that is named "Attribute 1"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
Xdmf Tree:
Attribute 1
! Adding an information named "Information 1"
tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 1
|Information 1
|}
Xdmf Tree:
Attribute 1
Information 1
! Adding an attribute that is named "Attribute 2"
! Centered on Nodex
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|-
|Attribute 2
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
Xdmf Tree:
Attribute 1
Attribute 2
|->Information 1
! Adding a set that is named "Set 1"
! A set of Node Type
! contains 12 float values loaded from myNodeAttribute
testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, &
myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
! Adding an attribute that is named "Attribute 3"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
! Adding an Information named "Information 2"
tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
Attribute 3
Information 2
! Adding a grid named "Unstructured Grid"
CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays.
! Note: Using hard coded indecies here
! the return value from any of the add functions
! such as XdmfAddInformation may also be used
CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3)
CALL XDMFADDPREVIOUSINFORMATION(obj, 2)
CALL XDMFADDPREVIOUSSET(obj, 1)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
Attribute 3
Information 2
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
Then we simply call add grid again to insert a grid with the current contents of the working arrays
! Adding a grid named "Unstructured Grid 2"
CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
|->Unstructured Grid 2
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
75d9e8256e26aeb3caaadb3953cae0a11fe91701
137
136
2014-11-07T19:19:08Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root.
After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain.
CALL XDMFINIT(obj, filename)
The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root.
===XdmfGridCollections===
After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to.
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Add a Grid Collection to the tree:
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Another Grid Collection is added:
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION.
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Remove a Grid Collection from the top of the stack:
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Returning a Grid Collection to the stack adds it to the top:
! Returning the Grid Collection contained in the domain at position 0 to the stack
CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added.
Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls.
CALL XDMFINIT(obj, filename)
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Xdmf Tree:
Domain
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Xdmf Tree
Domain
|->Grid Collection
|->Grid Collection2
! Removing the grid Collection from the top of the stack.
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
! Adding a Grid Collection named "Grid Collection3"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
===Xdmf Arrays and other Data===
====Adding Data to Grids====
When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within.
{| class="wikitable"
!Object
!Working Arrays Cleared
|-
|GridCollection
|Attributes, Information, Maps, Sets
|-
|Grid
|Attributes, Information, Maps, Sets
|-
|Attribute
|Information
|-
|Information
|None
|-
|Map
|none
|-
|Set
|Attributes, Information
|}
====Retrieving Data from Closed Grids====
After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called.
! Adding an attribute that is named "Attribute 1"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
Xdmf Tree:
Attribute 1
! Adding an information named "Information 1"
tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 1
|Information 1
|}
Xdmf Tree:
Attribute 1
Information 1
! Adding an attribute that is named "Attribute 2"
! Centered on Nodex
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|-
|Attribute 2
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
Xdmf Tree:
Attribute 1
Attribute 2
|->Information 1
! Adding a set that is named "Set 1"
! A set of Node Type
! contains 12 float values loaded from myNodeAttribute
testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, &
myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
! Adding an attribute that is named "Attribute 3"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
! Adding an Information named "Information 2"
tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
Attribute 3
Information 2
! Adding a grid named "Unstructured Grid"
CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
====Adding Previously Created Datasets====
If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays.
! Note: Using hard coded indecies here
! the return value from any of the add functions
! such as XdmfAddInformation may also be used
CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3)
CALL XDMFADDPREVIOUSINFORMATION(obj, 2)
CALL XDMFADDPREVIOUSSET(obj, 1)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
Attribute 3
Information 2
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
Then we simply call add grid again to insert a grid with the current contents of the working arrays
! Adding a grid named "Unstructured Grid 2"
CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
|->Unstructured Grid 2
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
f7b4907aaa10bfabf196d31740bd7c6e75418091
138
137
2014-11-07T19:58:29Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
__TOC__
==XDMF API==
The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root.
After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain.
CALL XDMFINIT(obj, filename)
The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root.
===XdmfGridCollections===
After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to.
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Add a Grid Collection to the tree:
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Another Grid Collection is added:
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION.
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Remove a Grid Collection from the top of the stack:
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Returning a Grid Collection to the stack adds it to the top:
! Returning the Grid Collection contained in the domain at position 0 to the stack
CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added.
Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls.
CALL XDMFINIT(obj, filename)
Xdmf API Grid Collection Stack:
Domain <-- top of stack
Xdmf Tree:
Domain
! Adding a Grid Collection named "Grid Collection"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
! Adding a Grid Collection named "Grid Collection2"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection2 <-- top of stack
Grid Collection
Domain
Xdmf Tree
Domain
|->Grid Collection
|->Grid Collection2
! Removing the grid Collection from the top of the stack.
CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
Xdmf API Grid Collection Stack:
Grid Collection <-- top of stack
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
! Adding a Grid Collection named "Grid Collection3"
CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), &
XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
===Xdmf Arrays and other Data===
====Adding Data to Grids====
When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within.
{| class="wikitable"
!Object
!Working Arrays Cleared
|-
|GridCollection
|Attributes, Information, Maps, Sets
|-
|Grid
|Attributes, Information, Maps, Sets
|-
|Attribute
|Information
|-
|Information
|None
|-
|Map
|none
|-
|Set
|Attributes, Information
|}
====Retrieving Data from Closed Grids====
After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called.
! Adding an attribute that is named "Attribute 1"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
Xdmf Tree:
Attribute 1
! Adding an information named "Information 1"
tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 1
|Information 1
|}
Xdmf Tree:
Attribute 1
Information 1
! Adding an attribute that is named "Attribute 2"
! Centered on Nodex
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 1
|Attribute 1
|-
|Attribute 2
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
Xdmf Tree:
Attribute 1
Attribute 2
|->Information 1
! Adding a set that is named "Set 1"
! A set of Node Type
! contains 12 float values loaded from myNodeAttribute
testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, &
myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
! Adding an attribute that is named "Attribute 3"
! Centered on Node
! Scalar type
! contains 12 float values loaded from myNodeAttribute
nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), &
XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
! Adding an Information named "Information 2"
tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0))
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
Attribute 3
Information 2
! Adding a grid named "Unstructured Grid"
CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
====Adding Previously Created Datasets====
If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays.
! Note: Using hard coded indecies here
! the return value from any of the add functions
! such as XdmfAddInformation may also be used
CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3)
CALL XDMFADDPREVIOUSINFORMATION(obj, 2)
CALL XDMFADDPREVIOUSSET(obj, 1)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|Attribute 3
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|Information 2
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|Set 1
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
Attribute 3
Information 2
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
Then we simply call add grid again to insert a grid with the current contents of the working arrays
! Adding a grid named "Unstructured Grid 2"
CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.)
{| class="wikitable"
!Attribute Working
!Attribute Archive
|-
|
|Attribute 1
|-
|
|Attribute 2
|-
|
|Attribute 3
|}
{| class="wikitable"
!Information Working
!Information Archive
|-
|
|Information 1
|-
|
|Information 2
|}
{| class="wikitable"
!Set Working
!Set Archive
|-
|
|Set 1
|}
Xdmf API Grid Collection Stack:
Grid Collection3 <-- top of stack
Grid Collection
Domain
Xdmf Tree:
Domain
|->Grid Collection
|->Grid Collection2
|->Grid Collection3
|->Unstructured Grid
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
|->Unstructured Grid 2
|->Set 1
|->Attribute 1
|->Attribute 2
|->Information 1
|->Attribute 3
|->Information 2
===Writing to File===
After using the above steps to construct the desired data structure, the structure can be written to file.
CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
CALL XDMFWRITE(obj, 'my_output.xmf'//CHAR(0), 10, .TRUE.)
Then the XdmfFortran API should be closed.
CALL XDMFCLOSE(obj)
===Reading from File===
The following call will read an Xdmf structure from a file and set the API's domain to the domain that was read from the file.
CALL XDMFREAD(obj, 'my_output.xmf'//CHAR(0))
===Retrieving Data from the Xdmf Structure===
====Opening Items====
When a Domain has been read from file no data is yet accessable. First the user needs to open the grids that the Domain contains.
Each object has a corresponding XDMFOPEN call, using an Unstructured Grid as an example:
CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 1, 1, 1, 1)
This call will open the unstructured grid at index 0 from the grid collection currently at the top of the stack. The Maps, Attributes, Information, and Sets of that grid will be placed in the appropriate working arrays based on the last four values passed accordingly. This example opens all of them.
====Retrieving/Modifying Data from Arrays====
When an array such as an Attribute is loaded into the working array, its attributes can be interacted with. XdmfRetrieveNumAttributes will produce the number of attributes currently loaded, which can then be referenced by index.
CALL XDMFRETRIEVENUMATTRIBUTES(obj, numContained)
PRINT *, 'Number of Grid Attributes: ', numContained
An Attribute's data can be retrieved like so:
CHARACTER*256 itemName, itemKey, itemValue, itemTag
INTEGER numContained, typeHolder
REAL*8 myNodeAttributeOutput(12)
CALL XDMFRETRIEVEATTRIBUTENAME(obj, 0, itemName, 256)
PRINT *, 'Attribute Name: ', itemName
CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 0, numContained)
PRINT *, "Number of Properties: ", numContained
CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
PRINT *, "Key: ", itemKey
PRINT *, "Value: ", itemValue
CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
PRINT *, "Value: ", itemValue
CALL XDMFRETRIEVEATTRIBUTETAG(obj, 0, itemTag, 256)
PRINT *, 'Attribute Tag: ', itemTag
CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 0, typeHolder)
PRINT *, 'Attribute Type: ', typeHolder
CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 0, typeHolder)
PRINT *, 'Attribute Center: ', typeHolder
CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 0, typeHolder)
PRINT *, 'Attribute Value Type: ', typeHolder
CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 0, numContained)
PRINT *, 'Number of Values: ', numContained
CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, myNodeAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
PRINT 3, myNodeAttributeOutput
3 FORMAT (' ', 3F6.1)
If you wanted to modify an Attribute's array instead of retrieve it.
CALL XDMFMODIFYATTRIBUTEVALUES(obj, &
startIndex, &
myNodeAttributeVals, &
XDMF_ARRAY_TYPE_FLOAT64, &
numVals, &
valueStartIndex, &
1, &
1)
e5666a422e3a05aa03615b406a5c312d709112f6
XDMF Model and Format
0
2
139
94
2014-11-07T20:00:41Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
3231041628019305600647b563bc68b6f4c0929d
Xdmf2 Model and Format Archive
0
26
140
2014-11-07T20:00:55Z
Burns
17
Created page with "[[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXt..."
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
dbfc6f7c2523db7dc46fae5158a538785450a26e
141
140
2014-11-07T20:36:16Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Subset''' - A variation of what was originally Hyperslab in Xdmf2. The Attributes of the tag specify a selection over the child array.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Subset'''
A ''Subset'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
<nowiki><Subset ConstructedType="DataItem" </nowiki>
DataType="UInt"
Dimensions="8"
Format="XML"
Precision="4"
SubsetDimensions="2 2 2"
SubsetStarts="0 0 0"
<nowiki>SubsetStrides="2 2 2"></nowiki>
<nowiki><DataItem DataType="Int"</nowiki>
Dimensions="1"
Format="XML"
<nowiki>Precision="4"></nowiki>
0
<nowiki></DataItem></nowiki>
<nowiki><DataItem DataType="UInt"</nowiki>
Dimensions="3 3 3"
Format="XML"
<nowiki>Precision="4"></nowiki>
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<nowiki</DataItem></nowiki>
<nowiki></Subset></nowiki>
The first DataItem child is what the subset is initially set to before its associated heavy data is read in.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The children ar assigned variables based on the VariableNames attribute. The first child is what the function is initialized to before reading in the operation thus it is not assigned a variable. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A+B"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="XML"
<nowiki>Precision="4"></nowiki>
1.0 2.0 3.0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="XML"
<nowiki>Precision="4"></nowiki>
4.1 5.2 6.3
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
The ConstructedType attribute allows function to produce Geometries and Topologies in addtion to standard Arrays. It inherits the attributes of the array subtype that it would produce.
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. It allows for the old concatenate JOIN in addition to the following operators: -,+,/,*,|(concatenate),#(interlace)
Add the value 10 to every element
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="10+A"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Multiply two arrays (element by element) and take the absolute value
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="ABS(A*B)"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Concatenate two arrays
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A|B"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A#B#C"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B|C"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data2
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
add849725360d8f5325400e7ea4dfa0557f03051
142
141
2014-11-07T21:04:34Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Subset''' - A variation of what was originally Hyperslab in Xdmf2. The Attributes of the tag specify a selection over the child array.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Subset'''
A ''Subset'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
<nowiki><Subset ConstructedType="DataItem" </nowiki>
DataType="UInt"
Dimensions="8"
Format="XML"
Precision="4"
SubsetDimensions="2 2 2"
SubsetStarts="0 0 0"
<nowiki>SubsetStrides="2 2 2"></nowiki>
<nowiki><DataItem DataType="Int"</nowiki>
Dimensions="1"
Format="XML"
<nowiki>Precision="4"></nowiki>
0
<nowiki></DataItem></nowiki>
<nowiki><DataItem DataType="UInt"</nowiki>
Dimensions="3 3 3"
Format="XML"
<nowiki>Precision="4"></nowiki>
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<nowiki</DataItem></nowiki>
<nowiki></Subset></nowiki>
The first DataItem child is what the subset is initially set to before its associated heavy data is read in.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The children ar assigned variables based on the VariableNames attribute. The first child is what the function is initialized to before reading in the operation thus it is not assigned a variable. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A+B"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="XML"
<nowiki>Precision="4"></nowiki>
1.0 2.0 3.0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="XML"
<nowiki>Precision="4"></nowiki>
4.1 5.2 6.3
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
The ConstructedType attribute allows function to produce Geometries and Topologies in addtion to standard Arrays. It inherits the attributes of the array subtype that it would produce.
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. It allows for the old concatenate JOIN in addition to the following operators: -,+,/,*,|(concatenate),#(interlace)
Add the value 10 to every element
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="10+A"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Multiply two arrays (element by element) and take the absolute value
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="ABS(A*B)"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Concatenate two arrays
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A|B"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A#B#C"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B|C"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data2
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
The old Xdmf2 style of functions is still supported in most cases.
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
A Grid can also consist of a collection of child grids arranged either temporally or spatially. This is known as a Grid Collection and is specified by setting the GridType attribute to "Collection"
<nowiki><Grid</nowiki>
CollectionType="Spatial"
GridType="Collection"
<nowiki>Name="Collection"></nowiki>
<nowiki><Grid Name="Grid0"></nowiki>
<nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 0
<nowiki></DataItem></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 1
<nowiki></DataItem></nowiki>
<nowiki></Geometry></nowiki>
<nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki>
<nowiki></Grid></nowiki>
<nowiki><Grid Name="Grid1"></nowiki>
<nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 1
<nowiki></DataItem></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 1
<nowiki></DataItem></nowiki>
<nowiki></Geometry></nowiki>
<nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki>
<nowiki></Grid></nowiki>
<nowiki></Grid></nowiki>
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. It contains a single floating point value.
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Subset (XdmfSubset)
As Parent and:
SubsetDimensions (no default) in KJI Order
SubsetStarts (no default) in KJI Order
SubsetStrides (no default) in KJI Order
* Function (XdmfFunction)
As Parent and:
Expression (no default)
VariableName "|" (no variables specified)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
5e689c4dcaf0fa3bd203ea5a0b625b4b60dc709b
143
142
2014-11-07T21:05:27Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Subset''' - A variation of what was originally Hyperslab in Xdmf2. The Attributes of the tag specify a selection over the child array.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Subset'''
A ''Subset'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
<nowiki><Subset ConstructedType="DataItem" </nowiki>
DataType="UInt"
Dimensions="8"
Format="XML"
Precision="4"
SubsetDimensions="2 2 2"
SubsetStarts="0 0 0"
<nowiki>SubsetStrides="2 2 2"></nowiki>
<nowiki><DataItem DataType="Int"</nowiki>
Dimensions="1"
Format="XML"
<nowiki>Precision="4"></nowiki>
0
<nowiki></DataItem></nowiki>
<nowiki><DataItem DataType="UInt"</nowiki>
Dimensions="3 3 3"
Format="XML"
<nowiki>Precision="4"></nowiki>
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
<nowiki</DataItem></nowiki>
<nowiki></Subset></nowiki>
The first DataItem child is what the subset is initially set to before its associated heavy data is read in.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The children ar assigned variables based on the VariableNames attribute. The first child is what the function is initialized to before reading in the operation thus it is not assigned a variable. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A+B"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="XML"
<nowiki>Precision="4"></nowiki>
1.0 2.0 3.0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="XML"
<nowiki>Precision="4"></nowiki>
4.1 5.2 6.3
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
The ConstructedType attribute allows function to produce Geometries and Topologies in addtion to standard Arrays. It inherits the attributes of the array subtype that it would produce.
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. It allows for the old concatenate JOIN in addition to the following operators: -,+,/,*,|(concatenate),#(interlace)
Add the value 10 to every element
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="10+A"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Multiply two arrays (element by element) and take the absolute value
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="ABS(A*B)"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Concatenate two arrays
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A|B"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<nowiki><Function</nowiki>
ConstructedType="DataItem"
DataType="Float"
Dimensions="3"
Expression="A#B#C"
Format="XML"
Precision="4"
<nowiki>VariableNames="|A|B|C"></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data0
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data1
<nowiki></DataItem></nowiki>
<nowiki><DataItem Dimensions="3"</nowiki>
DataType="Float"
Format="HDF"
<nowiki>Precision="4"></nowiki>
data.h5:Data2
<nowiki></DataItem></nowiki>
<nowiki></DataItem></nowiki>
The old Xdmf2 style of functions is still supported in most cases.
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
A Grid can also consist of a collection of child grids arranged either temporally or spatially. This is known as a Grid Collection and is specified by setting the GridType attribute to "Collection"
<nowiki><Grid</nowiki>
CollectionType="Spatial"
GridType="Collection"
<nowiki>Name="Collection"></nowiki>
<nowiki><Grid Name="Grid0"></nowiki>
<nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 0
<nowiki></DataItem></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 1
<nowiki></DataItem></nowiki>
<nowiki></Geometry></nowiki>
<nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki>
<nowiki></Grid></nowiki>
<nowiki><Grid Name="Grid1"></nowiki>
<nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 1
<nowiki></DataItem></nowiki>
<nowiki><DataItem</nowiki>
DataType="Float"
Dimensions="3"
Format="XML"
<nowiki>Precision="8"></nowiki>
1 1 1
<nowiki></DataItem></nowiki>
<nowiki></Geometry></nowiki>
<nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki>
<nowiki></Grid></nowiki>
<nowiki></Grid></nowiki>
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. It contains a single floating point value.
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Subset (XdmfSubset)
As Parent and:
SubsetDimensions (no default) in KJI Order
SubsetStarts (no default) in KJI Order
SubsetStrides (no default) in KJI Order
* Function (XdmfFunction)
As Parent and:
Expression (no default)
VariableName "|" (no variables specified)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
Value (no default - Only valid for TimeType="Single")
27a2f89d8e3a0dd674dab4513ecd79211bcca810
User:Dhuckaby
2
27
151
2015-01-12T15:08:11Z
Dave.demarle
5
Creating user page for new user.
wikitext
text/x-wiki
Mechanical Engineer
National Energy Technology Laboratory
18d059e7638cfaedf741784596e66f3fa8445a6e
User talk:Dhuckaby
3
28
152
2015-01-12T15:08:11Z
Dave.demarle
5
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 10:08, 12 January 2015 (EST)
e0d91444b4220252d6b1a6b8dbde7b5dd89376f7
V3 Road Feature Request
0
15
153
95
2015-01-12T20:06:59Z
Dhuckaby
20
/* Version 3 Feature Request' */
wikitext
text/x-wiki
== Version 3 Feature Request' ==
'''Implement AttributeType=Matrix'''
I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items.
<Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" >
<DataItem Dimensions="3 2" Format="XML" >
0 0
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
<Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" >
<DataItem Dimensions="3 2" Format="XML" >
0 1
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
I would rather do something like this:
<Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix">
<DataItem Dimensions="2 1" Format="XML" >2 1</DataItem>
<DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4">
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</Attribute>
Or something like that.
'''1DCoRectMesh'''
I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data.
'''Polyhedral Cells'''
It would be great to have the XDMF specification and library support polyhedral cells
http://public.kitware.com/Bug/view.php?id=14528
4efb61b19e3656219a262b91e7d2aee15a8ae866
154
153
2015-01-12T20:07:43Z
Dhuckaby
20
/* Version 3 Feature Request' */
wikitext
text/x-wiki
== Version 3 Feature Request' ==
'''Implement AttributeType=Matrix'''
I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items.
<Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" >
<DataItem Dimensions="3 2" Format="XML" >
0 0
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
<Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" >
<DataItem Dimensions="3 2" Format="XML" >
0 1
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
I would rather do something like this:
<Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix">
<DataItem Dimensions="2 1" Format="XML" >2 1</DataItem>
<DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4">
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</Attribute>
Or something like that.
'''1DCoRectMesh'''
I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data.
'''Polyhedral Cells'''
It would be great to have the XDMF specification and library support polyhedral cells
http://public.kitware.com/Bug/view.php?id=14528
a47212f48577a83e321b0093d1d77a90e03a42f4
157
154
2015-04-17T15:19:37Z
Chrisr
21
/* Version 3 Feature Request' */
wikitext
text/x-wiki
== Version 3 Feature Request' ==
'''Implement AttributeType=Matrix'''
I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items.
<Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" >
<DataItem Dimensions="3 2" Format="XML" >
0 0
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
<Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell">
<DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" >
<DataItem Dimensions="3 2" Format="XML" >
0 1
1 1
757136 1 </DataItem>
<DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" >
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</DataItem>
</Attribute>
I would rather do something like this:
<Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix">
<DataItem Dimensions="2 1" Format="XML" >2 1</DataItem>
<DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4">
Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels
</DataItem>
</Attribute>
Or something like that.
'''1DCoRectMesh'''
I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data.
'''Polyhedral Cells'''
It would be great to have the XDMF specification and library support polyhedral cells
http://public.kitware.com/Bug/view.php?id=14528
'''Set'''
Already implemented (unofficially?) by VTK [https://github.com/Kitware/VTK/blob/master/ThirdParty/xdmf2/vtkxdmf2/libsrc/XdmfSet.h XdmfSet.h], this is pretty similar to the '''GridType="Subset"'''.
This would be useful for specifying boundary conditions on models. However, it needs a clearer definition of how to access Edges and Faces in 2D and 3D. e.g. they could be identified by CellId and then the cell-local FaceId/EdgeId?
93bce9282d68afb658c1590d5c8ca8321c5da2da
User:Chrisr
2
29
155
2015-04-17T13:43:29Z
Dave.demarle
5
Creating user page for new user.
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
User talk:Chrisr
3
30
156
2015-04-17T13:43:30Z
Dave.demarle
5
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 09:43, 17 April 2015 (EDT)
3d30d8097abf7a766f922adeddcb6f9e41890ab9
User:Milanberjan
2
31
158
2015-05-01T14:05:35Z
Dave.demarle
5
Creating user page for new user.
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
User talk:Milanberjan
3
32
159
2015-05-01T14:05:36Z
Dave.demarle
5
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 10:05, 1 May 2015 (EDT)
e6d8564afa5e700a0088b8c2d109cea268cfbec2
XDMF Model and Format
0
2
160
139
2015-06-01T09:38:30Z
Chrisr
21
Update description of Edge and Face based attributes
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
c5f69aeabddd2f0d9f1186f558a81623006715ff
161
160
2015-06-01T10:29:09Z
Chrisr
21
Add definition of <Set>
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Node">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
4f97ac20f79731d8b488792e2e68a6f6ea6a3c66
162
161
2015-06-03T11:41:03Z
Chrisr
21
typo
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<Domain>'''
'''<Grid Name="Two Quads>'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
ef8125bc78a4f11118234a71b8995b8240ab66a3
167
162
2016-03-26T06:58:44Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2"/>'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
27a33e6087d903a3fadb8f09ea58ad585db8b009
168
167
2016-03-26T07:31:45Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 2 6 5'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
296e76ff539924aff9e9c5d13b3f036f0a627a9e
169
168
2016-03-26T11:14:57Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads>'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
f0ff962d8d0a423fd55148bced08ff0690364e5b
170
169
2016-03-26T11:17:41Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
ab844afb139b109153da1f1771f9fb5feb311746
172
170
2016-03-26T12:26:29Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
6b7704c1014b81faeb9921abd1ad38f555babb08
173
172
2016-03-26T12:48:16Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
7c8cbf0d0b9c07877e83d6ff3e1870c9b9eb2177
175
173
2016-03-27T04:55:02Z
Mn1729
23
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''XML'''
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
5f112e968e2f3be5c70a282b86eb4281fe0578e4
186
175
2016-04-10T09:48:35Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
[[Xdmf2 Model and Format Archive]]
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
bed4cf18cf121741e8cc3317223d035c492fa84f
187
186
2016-04-10T09:51:48Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
8c238e125fcb1d90a5af1d40e61780cf027421df
188
187
2016-04-10T09:51:59Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form :
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :
'''XInclude'''
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
'''XPath'''
This allows for elements in the XML document and the API to reference specific elements in a document. For example :
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags. So a minimal (empty) XDMF XML file would be :
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.
'''Entities'''
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
'''XDMF Elements'''
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
71d886df1c680b9327449c62e955d242a7e99777
189
188
2016-04-10T10:04:43Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
'''XdmfItem'''
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
'''Uniform '''
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
'''Collection and Tree'''
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
160fde70036a07df0cb6ac3d0279f9641d1993eb
190
189
2016-04-10T10:05:49Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
'''HyperSlab and Coordinate'''
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
'''Function'''
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
'''Grid'''
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
'''Topology'''
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
'''Geometry'''
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
e127b1db12ed4f5c4e426d47a9dc8309319b9f11
191
190
2016-04-10T10:06:51Z
MDiehl
25
/* XdmfItem */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be :
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files. In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements :
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem.
====HyperSlab and Coordinate====
A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="2"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a
CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children :
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined :
'''Linear'''
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
'''Arbitrary'''
* Mixed - a mixture of unstructured cells
'''Structured'''
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity :
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) :
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
'''Attribute'''
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
'''Set'''
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
'''Time'''
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
'''Information'''
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
ea6a9ab5c5ff43264d0d1cd00a261293ec585df4
192
191
2016-04-10T10:13:19Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====Coordinate====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
9cfdd2acb2ac09344ebf7b3945a693132ba9c3b1
193
192
2016-04-10T10:15:37Z
MDiehl
25
/* Grid */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====Coordinate====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
===Uniform, Collection, and Tree===
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
===SubSet===
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
dd7b5dee5945eeabeec516048ac45f0760db4754
194
193
2016-04-10T10:19:01Z
MDiehl
25
/* XDMF Elements */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
===Uniform, Collection, and Tree===
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
===SubSet===
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
'''Quadratic'''
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology :
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and
subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future.
'''XML Element (Xdmf ClassName) and Default XML Attributes'''
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
6c55badd698b3bf200cf8a67bf29bfa2b9169737
195
194
2016-04-10T10:20:37Z
MDiehl
25
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElement (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
3f94b30f7c0379804b1a13ccf26ac5010612c2f2
196
195
2016-04-19T13:16:06Z
Dave.demarle
5
correct type
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
BaseOffset <span style='color:red'>0</span> | #
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
2847f17ff901f5de9f7b9025fe2458439eb0e60c
199
196
2016-04-21T15:26:17Z
Jgflemin
26
removed BaseOffset and provided an explanation that this was originally available in XDMF but is not available in XDMF3
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
''CData''
</ElementTag>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
40be091c9f67082bb077f443e1ad27a0b6b5d7c2
200
199
2016-05-19T23:34:47Z
Crayzeewulf
24
/* Elements */ Placed XML code in source tag so it is easier to edit and is lot easier to read.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>">'''
'''<xi:include href="Example3.xmf"/>'''
'''</Xdmf>'''
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
1681b8689df563ac165e8cdad0249565996a636f
User:Mn1729
2
33
163
2016-03-25T13:53:14Z
Dave.demarle
5
Creating user page for new user.
wikitext
text/x-wiki
I use HDF for meshes and found some mistakes in some of the xml file formats on this page. I would like to correct them for future users.
06991b38b4b8c65c2c68bb881fdf71674cedd44a
User talk:Mn1729
3
34
164
2016-03-25T13:53:14Z
Dave.demarle
5
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 09:53, 25 March 2016 (EDT)
a083f18f45c690779f899ae6874eae904175c4f6
User:Crayzeewulf
2
35
165
2016-03-25T15:08:46Z
WikiSysop
11
Creating user page for new user.
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
User talk:Crayzeewulf
3
36
166
2016-03-25T15:08:46Z
WikiSysop
11
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:WikiSysop|WikiSysop]] ([[User talk:WikiSysop|talk]]) 11:08, 25 March 2016 (EDT)
1ce72ee2a7e5396f9474387d6409628bedd2b3de
File:3DUnstructuredMesh.jpeg
6
37
171
2016-03-26T12:06:29Z
Mn1729
23
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:3DUnstructuredParaView.png
6
38
174
2016-03-27T04:48:28Z
Mn1729
23
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Get Xdmf
0
20
176
123
2016-04-02T19:37:53Z
Dave.demarle
5
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on zlib and hdf5 and had a header only dependency on boost. You must obtain and build those projects before you can build xdmf.
To use Xdmf from Python, Tcl or Java you will also need swig.
To obtain xdmf:
* git clone git://public.kitware.com/Xdmf.git XDMF
* mkdir build
* cd build
* ccmake ..
* make
To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake.
Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration.
99d8bc7946972d4653ed78f77a55d3369c30ea3e
177
176
2016-04-02T19:38:16Z
Dave.demarle
5
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on zlib and hdf5 and had a header only dependency on boost. You must obtain and build those projects before you can build xdmf.
To use Xdmf from Python, Tcl or Java you will also need swig.
To obtain xdmf:
* git clone git://public.kitware.com/Xdmf.git
* mkdir build
* cd build
* ccmake ..
* make
To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake.
Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration.
fa13076929901decd0ef887481f3271f03809740
183
177
2016-04-03T13:01:28Z
Dave.demarle
5
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on hdf5 and has a header only dependency on boost. You must obtain and build those projects before you can build xdmf.
To use Xdmf from Python or Java you will also need swig.
To obtain xdmf:
* git clone git://xdmf.org/Xdmf.git
* mkdir build
* cd build
* ccmake ..
* make
To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake.
Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration.
63712dcb86cf62a411e1204bf92a001e66746d40
Version 2
0
17
178
107
2016-04-03T12:27:18Z
Dave.demarle
5
wikitext
text/x-wiki
Version "2" of Xdmf is being deprecated but it can be found at:
git clone git://xdmf.org/Xdmf.git
There were two important branches in the repository, "master" (git SHA 6ca45404) and "pv". The "pv" branch (git SHA 24470abd) was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system.
The updates to Xdmf in version 2 are summarized in this paper:
[http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792]
and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3]
bcbfc6894dbd1c5d1cdc8b0e26195f2d5cfbadec
179
178
2016-04-03T12:27:45Z
Dave.demarle
5
wikitext
text/x-wiki
Version "2" of Xdmf is being deprecated but it can be found in the history at:
git clone git://xdmf.org/Xdmf.git
There were two important branches in the repository, "master" (git SHA 6ca45404) and "pv". The "pv" branch (git SHA 24470abd) was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system.
The updates to Xdmf in version 2 are summarized in this paper:
[http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792]
and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3]
f6ae3917d0a158ac3158485a979954d2ba085367
180
179
2016-04-03T12:28:35Z
Dave.demarle
5
wikitext
text/x-wiki
Version "2" of Xdmf is being deprecated but it can be found in the history at:
git clone git://xdmf.org/Xdmf.git
There were two important branches in the repository, "master" (git SHA 6ca45404) and "pv" (git SHA 24470abd). The "pv" branch was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system.
The updates to Xdmf in version 2 are summarized in this paper:
[http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792]
and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3]
376b0da226cf263432326f98c1347e0fdbe15bc1
Version 3
0
19
181
108
2016-04-03T12:29:55Z
Dave.demarle
5
wikitext
text/x-wiki
Version "3" of Xdmf is the master branch of:
git://xdmf.org/Xdmf.git
The initial plans for changes that went into version 3 are summarized on:
[http://xdmf.org/index.php/Xdmf::New()]
The overall goals included better performance and use of modern and more maintainable C++ programming idioms. This version adds a dependence on boost.
Additionally, this version added support for Graph types and removed support for the SQL back end.
7e0a0c25a907edf50518617c940c1dcb093a6902
Version 1
0
18
182
101
2016-04-03T12:44:49Z
Dave.demarle
5
wikitext
text/x-wiki
Version "1" of xdmf is deprecated but it can be obtained via:
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login
cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf
c1ef3acaa082158559158a150f25f09ea051b912
User:MDiehl
2
39
184
2016-04-09T21:52:22Z
Matthew.bowman
6
Creating user page for new user.
wikitext
text/x-wiki
Scientist, materials science and materials mechanics.
b0f4ed02462baadd1c9f264a0cc0d1a5485941f5
User talk:MDiehl
3
40
185
2016-04-09T21:52:22Z
Matthew.bowman
6
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:Matthew.bowman|Matthew.bowman]] ([[User talk:Matthew.bowman|talk]]) 17:52, 9 April 2016 (EDT)
0acbb2bb7c2dd9bfa74471bb508b35b4e8645d52
User:Jgflemin
2
41
197
2016-04-19T13:54:43Z
Dave.demarle
5
Creating user page for new user.
wikitext
text/x-wiki
I am the Lead Developer and Operator for the ADCIRC Surge Guidance System (ASGS) (https://github.com/jasonfleming/asgs), a software automation system and collection of utilities for the finite element ADCIRC (ADvanced Circulation) coastal ocean model (http://www.adcirc.org). I implemented the i/o code in ADCIRC for natively reading and writing XDMF data files using the Fortran XDMF API. I've also created/maintain/extend standalone utility programs that convert to/from ADCIRC ascii file format to XDMF format using the Fortran XDMF API. Finally, I have created/maintain/extend standalone utility programs that generate XDMF-compliant XML files for ADCIRC's native NetCDF4 formatted output files, taking advantage of the fact that NetCDF4 uses the HDF5 library underneath to write the files. This results in a set of output files that simultaneously satisfies the NetCDF4, HDF5, and XDMF format standards. More information is available from http://www.seahorsecoastal.com.
64193cf17e73f8da35db2d9e1641a5df1884226a
User talk:Jgflemin
3
42
198
2016-04-19T13:54:43Z
Dave.demarle
5
Welcome!
wikitext
text/x-wiki
'''Welcome to ''XdmfWeb''!'''
We hope you will contribute much and well.
You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages].
Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 09:54, 19 April 2016 (EDT)
838d14b561c6547c590636a61807ec7c4466b9dc
XDMF Model and Format
0
2
201
200
2016-05-19T23:36:37Z
Crayzeewulf
24
/* XInclude */ Placed XML in source tag so it get syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
'''/Xdmf/Domain/Grid'''
The tenth Grid .... XPath is one based.
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>'''
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
'''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>'''
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0">'''
'''</Xdmf>'''
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
4c1658281b709158aab0d256da85b7f2d077f0ef
202
201
2016-05-19T23:42:07Z
Crayzeewulf
24
/* XPath */ Placed code in source tags so it gets syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>'''
'''<!ENTITY cellDimsZYX "45 30 120">'''
'''<nowiki>]</nowiki>>'''
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
bdeade9a01de2b5fceead14f2ddc7bf5ee57773b
203
202
2016-05-19T23:43:35Z
Crayzeewulf
24
/* Entities */ Place code in source tags so it gets syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
abf6e554dbc194bebef0086034b628fe2213bd8e
204
203
2016-05-19T23:43:48Z
Crayzeewulf
24
/* Entities */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
'''<DataItem ItemType="Uniform"'''
'''Format="XML"'''
'''NumberType="Float" Precision="4"'''
'''Rank="1" Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
Alternatively, an application may store its data in binary files.
In this case the XML might be.
'''<DataItem ItemType="Uniform"'''
'''Format="Binary"'''
'''Dimensions="64 128 256">'''
'''PressureFile.bin'''
'''</DataItem>'''
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
cdfb5d5166cd0949e688c876e51eb2537c8c07f2
205
204
2016-05-19T23:48:25Z
Crayzeewulf
24
/* Uniform */ Placed code in source tags so it get syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
'''<DataItem Name="Tree Example" ItemType="Tree">'''
'''<DataItem ItemType="Tree">'''
'''<DataItem Name="Collection 1" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''4 5 6 7'''
'''</DataItem>'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem Name="Collection 2" ItemType="Collection">'''
'''<DataItem Dimensions="3">'''
'''7 8 9'''
'''</DataItem>'''
'''<DataItem Dimensions="4">'''
'''10 11 12 13'''
'''</DataItem>'''
'''</DataItem>'''
'''<DataItem ItemType="Uniform"'''
'''Format="HDF"'''
'''NumberType="Float" Precision="8"'''
'''Dimensions="64 128 256">'''
'''OutputData.h5:/Results/Iteration 100/Part 2/Pressure'''
'''</DataItem>'''
'''</DataItem>'''
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
1d0c118e6362d6f72755994bce074c66edddedaf
206
205
2016-05-19T23:51:13Z
Crayzeewulf
24
/* Collection and Tree */ Cleaned up code indentation. Placed code in source tags so it get syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
'''<DataItem ItemType="HyperSlab"'''
'''Dimensions="25 50 75 3"'''
'''Type="HyperSlab">'''
'''<DataItem'''
'''Dimensions="3 4"'''
'''Format="XML">'''
'''0 0 0 0 '''
'''2 2 2 1 '''
'''25 50 75 3'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
f263af9a950780e9a2384cdd98939c69ceedfbe9
207
206
2016-05-19T23:52:50Z
Crayzeewulf
24
/* HyperSlab */ Cleaned up code indentation. Placed code in source tags so it gets syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
'''<DataItem ItemType="Coordinate"'''
'''Dimensions="2"'''
'''Type="Coordinate">'''
'''<DataItem'''
'''Dimensions="2 4"'''
'''Format="XML">'''
'''0 0 0 1'''
'''99 199 299 0'''
'''</DataItem>'''
'''<DataItem'''
'''Name="Points"'''
'''Dimensions="100 200 300 3"'''
'''Format="HDF">'''
'''MyData.h5:/XYZ'''
'''</DataItem>'''
'''</DataItem>'''
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
c6e262bb5548c8fd075a42762cb6a5f907425373
208
207
2016-05-19T23:55:03Z
Crayzeewulf
24
/* Coordinate */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
'''<DataItem ItemType="Function" '''
'''Function="$0 + $1"'''
'''Dimensions="3">'''
'''<DataItem Dimensions="3">'''
'''1.0 2.0 3.0'''
'''</DataItem>'''
'''<DataItem Dimensions="3">'''
'''4.1 5.2 6.3'''
'''</DataItem>'''
'''</DataItem>'''
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
'''<DataItem Name="MyFunction" ItemType="Function"'''
''' Function="10 + $0">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Multiply two arrays (element by element) and take the absolute value
''' <DataItem ItemType="Function"'''
''' Function="ABS($0 <nowiki>*</nowiki> $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Select element 5 thru 15 from the first DataItem
''' <DataItem ItemType="Function"'''
''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Concatenate two arrays
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 ; $1)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />'''
''' </DataItem>'''
Interlace 3 arrays (Useful for describing vectors from scalar data)
''' <DataItem ItemType="Function"'''
''' Function="JOIN($0 , $1, $2)">'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />'''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> '''
''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />'''
''' </DataItem>'''
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
3ab21dac9044c67002a2c6e20f42e4de7c262477
209
208
2016-05-20T00:00:36Z
Crayzeewulf
24
/* Function */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
'''<Grid Name="Car Wheel" GridType="Tree">'''
'''<Grid Name="Tire" GridType="Uniform">'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nuts" GridType="Collection">'''
'''<Grid Name="Lug Nut 0" GridType="Uniform"'''
'''<Topology ....'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 1" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''<Grid Name="Lug Nut 2" GridType="Uniform"'''
'''<Topology ...'''
'''<Geometry ...'''
'''</Grid>'''
'''</Grid>'''
'''.'''
'''.'''
'''.'''
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
a6d5f7e0674bce24ac636f67b64b830c899d6d27
210
209
2016-05-20T00:09:39Z
Crayzeewulf
24
/* Uniform, Collection, and Tree */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
''' <Grid Name="Portion" GridType="Subset" Section="DataItem">'''
''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->''
''' <DataItem'''
''' DataType="Int"'''
''' Dimensions="2"'''
''' Format="XML">'''
''' 0 2'''
''' </DataItem>'''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="2">'''
''' 100 150'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
Or
''' <Grid Name="Portion" GridType="Subset" Section="All">'''
''<!-- Select the entire grid and add an attribute -->''
''' <Grid Name="Target" Reference="XML">'''
''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>'''
''' </Grid>'''
''' <Attribute Name="New Values" Center="Cell">'''
''' <DataItem Format="XML" Dimensions="3">'''
''' 100 150 200'''
''' </DataItem>'''
''' </Attribute>'''
''' </Grid>'''
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
266e34737da77b5a298cdafc1bfd1f5468e71a9d
211
210
2016-05-20T00:11:20Z
Crayzeewulf
24
/* SubSet */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
4facd07c06b3ad2c6d7ad1d1c9a59f818e665fa8
212
211
2016-05-20T00:11:50Z
Crayzeewulf
24
/* SubSet */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
'''<Topology TopologyType="Mixed" NumberOfElements="3" >'''
'''<DataItem Format="XML" DataType="Int" Dimensions="20">'''
'''6 0 1 2 7'''
'''3 4 4 5 6 7'''
'''9 8 9 10 11 12 13 14 15'''
'''</DataItem>'''
'''</Topology>'''
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
ba855a9b71e9c53fa658861932d55120483d0f1f
213
212
2016-05-20T03:33:28Z
Crayzeewulf
24
/* Structured */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element :
'''<Information Name="XBounds" Value="0.0 10.0"/>'''
'''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>'''
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
67141f0bdf071a2b7499f3de7e444057d18986af
214
213
2016-05-20T03:35:19Z
Crayzeewulf
24
/* Information */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<Grid Name="Two Quads">'''
'''<Topology TopologyType="Quadrilateral" NumberOfElements="2">'''
'''<DataItem Format="XML" DataType="Int" Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry GeometryType="XYZ">'''
'''<DataItem Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
'''<?xml version="1.0" ?>'''
'''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>'''
'''<Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]">'''
'''<Domain>'''
'''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">'''
'''0.0 0.0 0.0'''
'''1.0 0.0 0.0'''
'''1.0 1.0 0.0'''
'''0.0 1.0 0.0'''
'''0.0 0.0 2.0'''
'''1.0 0.0 2.0'''
'''1.0 1.0 2.0'''
'''0.0 1.0 2.0'''
'''</DataItem>'''
'''<Grid Name="Two Quads">'''
'''<Topology Type="Quadrilateral" NumberOfElements="2" >'''
'''<DataItem Format="XML" '''
'''DataType="Int"'''
'''Dimensions="2 4">'''
'''0 1 2 3'''
'''1 6 7 2'''
'''</DataItem>'''
'''</Topology>'''
'''<Geometry Type="XYZ">'''
'''<DataItem Reference="XML">'''
'''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>'''
'''</DataItem>'''
'''</Geometry>'''
'''</Grid>'''
'''</Domain>'''
'''</Xdmf>'''
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
522c57b4e250a73b6dfa8be121efca3ee2181f62
215
214
2016-05-20T17:13:14Z
Crayzeewulf
24
/* Geometry */ Cleaned up indentation of sample XML code. Placed code in source tags so it gets syntax highlighting and is easier to read/edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
'''<Attribute Name="Node Values" Center="Node">'''
'''<DataItem Format="XML" Dimensions="6 4">'''
'''100 200 300 400'''
'''500 600 600 700'''
'''800 900 1000 1100'''
'''1200 1300 1400 1500'''
'''1600 1700 1800 1900'''
'''2000 2100 2200 2300'''
'''</DataItem>'''
'''</Attribute>'''
Or assigned to the cell centers :
'''<Attribute Name="Cell Values" Center="Cell">'''
'''<DataItem Format="XML" Dimensions="3">'''
''' 3000 2000 1000'''
''' </DataItem>'''
'''</Attribute>'''
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
99c84621e5ccf57c678490a938117fda054797f4
216
215
2016-05-20T17:15:21Z
Crayzeewulf
24
/* Attribute */ Cleaned up indentation of XML sample code. Placed all code in source tags so it gets syntax highlighting and is easier to read/edit.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
'''<Set Name="Ids" SetType="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 1 2 3 4'''
''' </DataItem>'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 0 0 0 0'''
''' </DataItem>'''
''' <Attribute Name="Example" Center="Face">'''
''' <DataItem Format="XML" Dimensions="4" >'''
''' 100.0 110.0 100.0 200.0'''
''' </DataItem>'''
''' </Attribute>'''
'''</Set>'''
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
7dfdd2eeb0b00fef243c207c62abfd49a8a496f6
217
216
2016-05-20T17:17:04Z
Crayzeewulf
24
/* Set */ Place XML sample code in source tags so it gets syntax highlighting and is easier to read/modify.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time :
'''<Time Value="0.1" />'''
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time :
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
For a collection of grids not written at regular intervals :
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
For data which is valid not at a discrete time but within a range :
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
42943f898447678ecdad4ec539a2fe8b4e35d658
218
217
2016-05-20T17:19:37Z
Crayzeewulf
24
/* Time */ Cleaned up indentation of sample XML code. Placed all code in source tags so it gets syntax highlighting and is easier to read/modify.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
d422aef10b574ea3489d358ab9b71d020294907f
219
218
2016-05-20T17:22:12Z
Crayzeewulf
24
/* XML Element (Xdmf ClassName) and Default XML Attributes */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
733a9293404824c093365f2d25694698338b6ba2
228
219
2016-10-20T20:25:31Z
Stevenwalton
28
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
42fd47f807ae745d8c6cec7ab8a2bc80184dc999
229
228
2016-12-13T16:02:22Z
Burns
17
Xdmf 3 only allows for individual times.
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. Currently the supported types of values are :
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
These values can be centered on :
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Typically Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
3295c3578935c566a1b1d531c2bccb5bc906ceae
241
229
2017-08-22T14:19:00Z
Michal
30
FiniteElementFunction added to /* Attribute */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain 4 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
* number of degrees of freedom in each cell
* ordering of cells
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
<DataItem Dimensions="9 1" NumberType="UInt" Format="XML">
0
3
6
9
12
15
18
21
24
</DataItem>
<DataItem Dimensions="8 1" NumberType="UInt" Format="XML">
0
1
2
3
4
5
6
7
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
<DataItem Dimensions="9 1" NumberType="UInt" Format="XML">
0
6
12
18
24
30
36
42
48
</DataItem>
<DataItem Dimensions="8 1" NumberType="UInt" Format="XML">
0
1
2
3
4
5
6
7
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
c77eea73d9db30785be1621452642f836d811812
242
241
2017-08-22T15:46:40Z
Michal
30
/* XML Element (Xdmf ClassName) and Default XML Attributes */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain 4 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
* number of degrees of freedom in each cell
* ordering of cells
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
<DataItem Dimensions="9 1" NumberType="UInt" Format="XML">
0
3
6
9
12
15
18
21
24
</DataItem>
<DataItem Dimensions="8 1" NumberType="UInt" Format="XML">
0
1
2
3
4
5
6
7
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
<DataItem Dimensions="9 1" NumberType="UInt" Format="XML">
0
6
12
18
24
30
36
42
48
</DataItem>
<DataItem Dimensions="8 1" NumberType="UInt" Format="XML">
0
1
2
3
4
5
6
7
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementType
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
511abb1ae621519f80a4266bcc66780969af0ed6
243
242
2017-08-22T16:46:39Z
Michal
30
/* XML Element (Xdmf ClassName) and Default XML Attributes */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain 4 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
* number of degrees of freedom in each cell
* ordering of cells
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
<DataItem Dimensions="9 1" NumberType="UInt" Format="XML">
0
3
6
9
12
15
18
21
24
</DataItem>
<DataItem Dimensions="8 1" NumberType="UInt" Format="XML">
0
1
2
3
4
5
6
7
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
<DataItem Dimensions="9 1" NumberType="UInt" Format="XML">
0
6
12
18
24
30
36
42
48
</DataItem>
<DataItem Dimensions="8 1" NumberType="UInt" Format="XML">
0
1
2
3
4
5
6
7
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
181b0eb6d960bebe22604acd751994a0254e9392
244
243
2017-08-22T20:37:42Z
Michal
30
/* Attribute */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
e10c863b812db878a75d36004a480fe6ed13781d
245
244
2018-05-05T12:17:20Z
Michal
30
Little inconsistency in GeometryType
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
* Mixed - a mixture of unstructured cells (see picture to right)
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
cd98b4aa13011bac4e72c337d8f08eacb83db599
246
245
2018-05-15T11:34:37Z
Houssen
31
Update documentation related to Mixed topology
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell.
If the cell is a polyhedron, the list of associated data describing each polyhedron is:
* number of faces of the polyhedron
* for each face: the number of nodes of the face, and, the list of each index of each node
Here is an example of an octahedron (polyhedron):
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
8770718916ba85884c53d428309b449288a1d5bf
247
246
2018-05-15T11:38:21Z
Houssen
31
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell.
If the cell is a polyhedron, the list of associated data describing each polyhedron is:
* number of faces of the polyhedron
* for each face: the number of nodes of the face, and, the list of each index of each node
Here is an example of an octahedron (polyhedron):
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
4ea8de6bbd80f495b8cb78826db751054b7bdcfa
248
247
2018-05-15T11:45:37Z
Houssen
31
Mixed topology: add octahedron example
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell.
If the cell is a polyhedron, the list of associated data describing each polyhedron is:
* number of faces of the polyhedron
* for each face: the number of nodes of the face, and, the list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
10244fd96561c382a49d6010f346a56bea78904f
249
248
2018-05-24T13:40:01Z
Chrisr
21
fix a typo
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell.
If the cell is a polyhedron, the list of associated data describing each polyhedron is:
* number of faces of the polyhedron
* for each face: the number of nodes of the face, and, the list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
0a523de05c58546b2a2c48b278978b9945ae9df1
250
249
2018-07-14T14:20:14Z
Houssen
31
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<source lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</source>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
62beaacf413c69e66288fa3a4f5be70010db3ef8
Get Xdmf
0
20
220
183
2016-05-20T17:48:26Z
Crayzeewulf
24
Added more detailed instructions for downloading and building Xdmf.
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig].
Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf.
* Clone the Git repository:
<source lang="sh">
git clone git://xdmf.org/Xdmf.git
</source>
* Create and enter the directory for building the code:
<source lang="sh">
cd Xdmf
mkdir build
cd build
</source>
* Prepare the CMake-based build. There are two options
*# Use the following command and select options using a text-based menu system:<source lang="sh">ccmake ..</source>
*# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following:
<source lang="sh">
cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \
-DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev
</source>
* Make and install Xdmf:
<source lang="sh">
make
make install
</source>
To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake.
Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration.
a300bc13bf4aead23b7f11a1a65579b7cda46240
221
220
2016-05-20T17:51:05Z
Crayzeewulf
24
Updated syntax highlighting language.
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig].
Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf.
* Clone the Git repository:
<source lang="bash">
git clone git://xdmf.org/Xdmf.git
</source>
* Create and enter the directory for building the code:
<source lang="bash">
cd Xdmf
mkdir build
cd build
</source>
* Prepare the CMake-based build. There are two options
*# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source>
*# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following:
<source lang="bash">
export XDMF_INSTALL_DIR=/opt/Xdmf/
cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \
-DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev
</source>
* Make and install Xdmf:
<source lang="bash">
make
make install
</source>
To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake.
Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration.
8150509a64c658fecefd87815703371e8ff33f6a
222
221
2016-05-20T17:53:07Z
Crayzeewulf
24
Added statement indicating that users will cmake to build Xdmf. Added link to CMake home page.
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. You will need [https://cmake.org/ CMake] to build Xdmf from source code. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig].
Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf.
* Clone the Git repository:
<source lang="bash">
git clone git://xdmf.org/Xdmf.git
</source>
* Create and enter the directory for building the code:
<source lang="bash">
cd Xdmf
mkdir build
cd build
</source>
* Prepare the CMake-based build. There are two options
*# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source>
*# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following:
<source lang="bash">
export XDMF_INSTALL_DIR=/opt/Xdmf/
cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \
-DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev
</source>
* Make and install Xdmf:
<source lang="bash">
make
make install
</source>
To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake.
Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration.
28eab31ff117fbc968bc6352571c55a5c517105c
224
222
2016-07-27T18:05:39Z
Crayzeewulf
24
wikitext
text/x-wiki
The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original]
Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. You will need [https://cmake.org/ CMake] to build Xdmf from source code. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig].
Xdmf development is now being hosted at Kitware's gitlab at: https://gitlab.kitware.com/xdmf/xdmf.
See [http://www.kitware.com/pipermail/xdmf/2016-April/000935.html this] post for additional details.
Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf.
* Clone the Git repository:
<source lang="bash">
git clone git://xdmf.org/Xdmf.git
</source>
or,
<source lang="bash">
git clone https://gitlab.kitware.com/xdmf/xdmf.git
</source>
* Create and enter the directory for building the code:
<source lang="bash">
cd Xdmf
mkdir build
cd build
</source>
* Prepare the CMake-based build. There are two options
*# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source>
*# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following:
<source lang="bash">
export XDMF_INSTALL_DIR=/opt/Xdmf/
cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \
-DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev
</source>
* Make and install Xdmf:
<source lang="bash">
make
make install
</source>
To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake.
Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration.
81f8bed6bd6a90309d32e5089543ab7dc8ebb7f6
237
224
2017-03-13T14:16:24Z
Burns
17
wikitext
text/x-wiki
The old version of this page can be found [http://xdmf.org/index.php/Get_Xdmf_original here.]
Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. You will need [https://cmake.org/ CMake] to build Xdmf from source code. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig].
Xdmf development is now being hosted at Kitware's gitlab at: https://gitlab.kitware.com/xdmf/xdmf.
See [http://www.kitware.com/pipermail/xdmf/2016-April/000935.html this] post for additional details.
Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf.
* Clone the Git repository:
<source lang="bash">
git clone git://xdmf.org/Xdmf.git
</source>
or,
<source lang="bash">
git clone https://gitlab.kitware.com/xdmf/xdmf.git
</source>
* Create and enter the directory for building the code:
<source lang="bash">
cd Xdmf
mkdir build
cd build
</source>
* Prepare the CMake-based build. There are two options
*# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source>
*# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following:
<source lang="bash">
export XDMF_INSTALL_DIR=/opt/Xdmf/
cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \
-DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev
</source>
* Make and install Xdmf:
<source lang="bash">
make
make install
</source>
To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake.
Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration.
02ab867ce6c833b35d83e03f4d9f05af181c7e12
Read Xdmf
0
8
223
146
2016-05-20T17:59:09Z
Crayzeewulf
24
/* Reading XDMF Data */ Placed code in source tags so it get syntax highlighting. Cleaned up indentation of the code.
wikitext
text/x-wiki
== Reading XDMF Data ==
[[Image:TwoHex.jpg]]
The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face.
There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are
all stored directly in the XML file.
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf>
<Domain>
<Grid Name="TestGrid">
<Topology Type="Hexahedron" NumberOfElements="2" >
<DataItem Format="XML" DataType="Float"
Dimensions="2 8">
0 1 7 6 3 4 10 9
1 2 8 7 4 5 11 10
</DataItem>
</Topology>
<Geometry Type="XYZ">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3 3">
0.0 0.0 1.0
1.0 0.0 1.0
3.0 0.0 2.0
0.0 1.0 1.0
1.0 1.0 1.0
3.0 2.0 2.0
0.0 0.0 -1.0
1.0 0.0 -1.0
3.0 0.0 -2.0
0.0 1.0 -1.0
1.0 1.0 -1.0
3.0 2.0 -2.0
</DataItem>
</Geometry>
<Attribute Name="NodeValues" Center="Node">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="4 3" >
100 200 300
300 400 500
300 400 500
500 600 700
</DataItem>
</Attribute>
<Attribute Name="CellValues" Center="Cell">
<DataItem Format="XML" DataType="Float" Precision="8"
Dimensions="2" >
100 200
</DataItem>
</Attribute>
</Grid>
</Domain>
</Xdmf>
</source>
The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and
retrieving the data values.
<source lang="python" line="1">
#! /usr/bin/env python
from Xdmf import *
reader = XdmfReader.New()
dom = XdmfReader.read('MyGrid.xmf')
# We now have a tree. Find the one and only Grid element
grid = dom.getUnstruturedGrid(0)
top = grid.GetTopology()
print 'Values = ', top.getValuesString()
# Release values from data when done
top.release()
geo = grid.GetGeometry()
print 'Geo Type = ', geo.getType().getName(), ' # Points = ', geo.getNumberPoints()
print 'Points = ', geo.getValuesString()
geo.release()
# for each Attribute, print Light Data and Values
for i in range(grid.getNumberAttributes()):
attr = grid.getAttribute(i)
print 'Attribute ', i, ' Name = ', attr.getName()
# Attribute HeavyData is not Updated by default
# there could potentially be many causing huge IO
attr.read()
print 'Values ', attr.getValuesString()
attr.release()
</source>
a52c255a4157453fad70ee09b5ef9ecde1c6763a
Main Page
0
1
225
145
2016-09-20T11:13:30Z
Arminw
27
/* web site administration */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Xdmf3 Fortran API|Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list.
=== Web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
4626a5afa4c53500d4f0c339c63504fe991f7964
226
225
2016-09-20T11:42:01Z
Arminw
27
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Xdmf3 Fortran API|Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [https://gitlab.kitware.com/xdmf/xdmf/issues GitLab issue tracker].
* The GitLab issue tracker is in use since September 2016. Bugs reported before this can be found from the [http://public.kitware.com/Bug/view_all_bug_page.php?project_id=4 Mantis Bugtracking system].
=== Web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
72c16dbd7719ea97a1cdf67c7c199dab78334614
230
226
2017-03-13T13:47:49Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Validate Xdmf's XML]]
# [[Xdmf3 Fortran API|Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [https://gitlab.kitware.com/xdmf/xdmf/issues GitLab issue tracker].
* The GitLab issue tracker is in use since September 2016. Bugs reported before this can be found from the [http://public.kitware.com/Bug/view_all_bug_page.php?project_id=4 Mantis Bugtracking system].
=== Web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
ec9aa7c16162eccdc520303a88d69483a85754ae
238
230
2017-03-13T18:15:32Z
Burns
17
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
<span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span>
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations.
Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement.
XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid.
The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values.
While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
'''More Detail'''
*[[XDMF Model and Format]]
*[[XDMF API]]
'''How do I ...'''
# [[Get Xdmf]]
# [[Read Xdmf]]
# [[Write Xdmf]]
# [[Validate Xdmf's XML]]
# [[Xdmf3 Fortran API|Write from Fortran]]
# [[Read from MySQL]]
# [[Parallel IO with MPI]]
'''Data Format Examples'''
* The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF
* Generate or read in data to ParaView, and save it into XDMF format.
* [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps]
* [[examples/imagedata | ImageData from h5 array]]
'''History and Road Map'''
* [[Version 1]]
* [[Version 2]]
* [[Version 3]]
* [[New Features]]
* [[V3_Road_Feature_Request|Feature Requests]]
* [[V2_To_V3|V2 to V3 Transition and bugs]]
'''Mailing list'''
* Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here]
'''Bug reports'''
* To report a bug or request a feature, go to the [https://gitlab.kitware.com/xdmf/xdmf/issues GitLab issue tracker].
* The GitLab issue tracker is in use since September 2016. Bugs reported before this can be found from the [http://public.kitware.com/Bug/view_all_bug_page.php?project_id=4 Mantis Bugtracking system].
=== Web site administration ===
'''Wiki Account'''
* Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so.
* [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ]
* [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
f1021945e2b494dd617e7f544a7107bd2158d724
File:MixedTopology.png
6
43
227
2016-10-20T17:04:31Z
Stevenwalton
28
Numbers to denote mixed topology. *means that you also need to include number of cells
wikitext
text/x-wiki
Numbers to denote mixed topology. *means that you also need to include number of cells
d212f1372ff92d1102a2ebe633978da615a4dc72
Validate Xdmf's XML
0
44
231
2017-03-13T13:51:01Z
Burns
17
Created page with "Xdmf's XML can be validated by referencing its .dtd file located at [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd]"
wikitext
text/x-wiki
Xdmf's XML can be validated by referencing its .dtd file located at [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd]
8f896b094de415943b16242ad99033d1b403b356
232
231
2017-03-13T13:51:21Z
Burns
17
wikitext
text/x-wiki
Xdmf's XML can be validated by referencing its .dtd file located at this location.[https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd]
7697a3b4d041f6845126b6150d3808612522f52d
233
232
2017-03-13T13:51:40Z
Burns
17
wikitext
text/x-wiki
Xdmf's XML can be validated by referencing its .dtd file (located at this location.)[https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd]
4da0992813d776087b5ee0f1605829f796189abf
234
233
2017-03-13T13:52:45Z
Burns
17
wikitext
text/x-wiki
Xdmf's XML can be validated by referencing its .dtd file located at this location.[https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd]
7697a3b4d041f6845126b6150d3808612522f52d
235
234
2017-03-13T13:53:40Z
Burns
17
wikitext
text/x-wiki
Xdmf's XML can be validated by referencing its .dtd file located [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd | at this location].
81470a7f279d09a0ae3f34ea88e98a976a9eb097
236
235
2017-03-13T13:53:55Z
Burns
17
wikitext
text/x-wiki
Xdmf's XML can be validated by referencing its .dtd file located [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd at this location].
450f5af56bb162ea5a1e007b64a6d88a7c66ca58
Parallel IO with MPI
0
12
239
149
2017-03-13T18:17:54Z
Burns
17
/* Distributed Shared Memory */
wikitext
text/x-wiki
<pre style="color: red">Note: as of version 1.8.13 hdf5 must be patched as follows to allow for this functionality.</pre>
In the file /hdf5/src/CMakeLists.txt
change
if (NOT HDF5_INSTALL_NO_DEVELOPMENT)
install (
FILES
${H5_PUBLIC_HEADERS}
DESTINATION
${HDF5_INSTALL_INCLUDE_DIR}
COMPONENT
headers
)
endif (NOT HDF5_INSTALL_NO_DEVELOPMENT)
to
if (NOT HDF5_INSTALL_NO_DEVELOPMENT)
install (
FILES
${H5_PUBLIC_HEADERS}
${H5_PRIVATE_HEADERS}
DESTINATION
${HDF5_INSTALL_INCLUDE_DIR}
COMPONENT
headers
)
endif (NOT HDF5_INSTALL_NO_DEVELOPMENT)
===Distributed Shared Memory===
By leveraging the h5fd and hdf5 libraries, Xdmf provides an interface by which a user can set up a dsm server that may be interacted with in a manner similar to hdf5.
Multiple Datasets and filenames are supported as of version 3.3.0.
====Initializing DSM====
After starting MPI, the DSM can be started by creating an instance of XdmfHDF5WriterDSM or XdmfHDF5ControllerDSM.
int size, id, dsmSize;
dsmSize = 64;//The total size of the DSM being created
std::string newPath = "dsm";
unsigned int numServersCores = 2;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Init(&argc, &argv);
MPI_Comm_rank(comm, &id);
MPI_Comm_size(comm, &size);
unsigned int dataspaceAllocated = dsmSize/numServersCores;
// Splitting MPICommWorld so that a comm that contains the non-Server cores exists.
MPI_Comm workerComm;
MPI_Group workers, dsmgroup;
MPI_Comm_group(comm, &dsmgroup);
int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
unsigned int index = 0;
for(int i=size-numServersCores ; i <= size-1 ; ++i)
{
ServerIds[index++] = i;
}
MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
int testval = MPI_Comm_create(comm, workers, &workerComm);
cfree(ServerIds);
// The last two cores in the Comm are regulated to manage the DSM.
shared_ptr<XdmfHDF5WriterDSM> exampleWriter =
XdmfHDF5WriterDSM::New(newPath, comm, dataspaceAllocated, size-numServersCores, size-1);
This creates a DSM buffer and manager which must be passed to any new DSM objects in order for those objects to function.
After the user is finished with DSM the manager must be disposed of. Not doing this will result in an error.
if (id == 0)
{
exampleWriter->stopDSM();
}
MPI_Barrier(comm);
//the dsmManager must be deleted or else there will be a segfault
exampleWriter->deleteManager();
MPI_Finalize();
A full example program can be found in the Xdmf source at: Xdmf/core/dsm/tests/Cxx/DSMLoopTest.cpp
0349b560af07acbb4f0e8318ca5d683dc1569ddb
New Features
0
45
240
2017-03-13T18:48:30Z
Burns
17
Created page with "Here are some new features to Xdmf. Try them out and give us some feedback. == [http://xdmf.org/index.php/Parallel_IO_with_MPI XdmfDSM] has been updated. == It now supports..."
wikitext
text/x-wiki
Here are some new features to Xdmf. Try them out and give us some feedback.
== [http://xdmf.org/index.php/Parallel_IO_with_MPI XdmfDSM] has been updated. ==
It now supports Paging, multiple datasets, and multiple files.
== New API ==
=== XML Archive for XdmfWriter ===
Archives the XML from previous writes and uses it to generate later iterations. Works best in simulations where new data is appended to the file each iteration.
shared_ptr<XdmfWriter> writer = XdmfWriter::New();
writer->setRebuildXML(false);
=== XdmfGridController ===
Alternative to XPointers, saves on memory by allowing the reading process to leave extra grids on file instead of reading them.
shared_ptr<XdmfUnstructuredGrid> equalUnGrid = XdmfUnstructuredGrid::New();
shared_ptr<XdmfGridController> unGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[1]");
equalUnGrid->setGridController(unGridController);
A full example program can be found in the Xdmf source at: Xdmf2/tests/Cxx/TestXdmfGridController.cpp
Will be usable in Paraview when it is updated to use the latest Xdmf.
=== XdmfTemplate ===
Allows for a grid collection to be written as a compressed grid.
A full example program can be found in the Xdmf source at: Xdmf2/tests/Cxx/TestXdmfGridTemplate.cpp
Requires a patch to VTK to render in Paraview:
In file ParaView/VTK/IO/Xdmf3vtkXdmf3DataSet.cxx
line 175 change
#define DO_DEEPREAD 0
to
#define DO_DEEPREAD 1
== Cxx11 replaces Boost ==
In the case that Cxx11 is available, the Cxx11 version of calls will be used. Reworked the internals of XdmfArray to no longer use boost::variant
df6ff4f3ec9eb6ffb2ea5d6aa3f41263ae2496bd
XDMF Model and Format
0
2
251
250
2022-12-01T16:29:47Z
Jgflemin
26
/* Elements */ source -> pre
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<pre lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</pre>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<source lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</source>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
9015e33393c4c2e07b6ba0393bae4c1c76159eb9
252
251
2022-12-01T16:31:11Z
Jgflemin
26
/* XInclude */ source -> pre
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<pre lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</pre>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<pre lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</pre>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<source>
/Xdmf/Domain/Grid
</source>
The tenth Grid .... XPath is one based.
<source>
/Xdmf/Domain/Grid[10]
</source>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<source>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</source>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</source>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
67d7bf6a49a89755379c065ec9dcebbbee95c7ae
253
252
2022-12-01T16:32:34Z
Jgflemin
26
/* XPath */ source -> pre
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<pre lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</pre>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<pre lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</pre>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<pre>
/Xdmf/Domain/Grid
</pre>
The tenth Grid .... XPath is one based.
<pre>
/Xdmf/Domain/Grid[10]
</pre>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<pre>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</pre>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</pre>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</source>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
96cb88354e72f6210574eb9ced2785dede2fba5b
254
253
2022-12-01T16:33:00Z
Jgflemin
26
/* Entities */
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<pre lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</pre>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<pre lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</pre>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<pre>
/Xdmf/Domain/Grid
</pre>
The tenth Grid .... XPath is one based.
<pre>
/Xdmf/Domain/Grid[10]
</pre>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<pre>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</pre>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</pre>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</pre>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</source>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<source lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Multiply two arrays (element by element) and take the absolute value
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Select element 5 thru 15 from the first DataItem
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</source>
Concatenate two arrays
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</source>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<source lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</source>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
902312724b21d3cd8453ce6ff5f563dd954b4c49
255
254
2022-12-01T16:34:46Z
Jgflemin
26
/* Function */ source -> pre
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<pre lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</pre>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<pre lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</pre>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<pre>
/Xdmf/Domain/Grid
</pre>
The tenth Grid .... XPath is one based.
<pre>
/Xdmf/Domain/Grid[10]
</pre>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<pre>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</pre>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</pre>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</pre>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<source lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</source>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</source>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<source lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</source>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<source lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</source>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<source lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<source lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</source>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</pre>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<pre lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</pre>
Multiply two arrays (element by element) and take the absolute value
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</pre>
Select element 5 thru 15 from the first DataItem
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</pre>
Concatenate two arrays
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</pre>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</pre>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<source lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</source>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</source>
Or
<source lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</source>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<source lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</source>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<source lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</source>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<source lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</source>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<source lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</source>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<source lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</source>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<source lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</source>
Or assigned to the cell centers :
<source lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</source>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<source lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</source>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<source lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</source>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<source lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</source>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<source lang="xml" line="1">
<Time Value="0.1" />
</source>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<source lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</source>
For a collection of grids not written at regular intervals:
<source lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</source>
For data which is valid not at a discrete time but within a range:
<source lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</source>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<source lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</source>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
8aa2aac42b0f4e2c0c987d574248f9f292df16d9
256
255
2022-12-01T16:43:07Z
Jgflemin
26
source -> pre
wikitext
text/x-wiki
[[Image:XdmfLogo1.gif]]
Here the XDMF3 Model and Format is described.
See [[Xdmf2 Model and Format Archive]] for the previous version.
The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'').
Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes.
XDMF categorizes data by two main attributes; size and function.
Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.).
In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components).
XDMF uses XML to store Light data and to describe the data Model.
Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data.
The data Format is stored redundantly in both XML and HDF5.
This allows tools to parse XML to determine the resources that will be required to access the Heavy data.
For the binary Heavy data option, the xml must list a filename where the binary data is stored.
While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java.
The API is not necessary in order to produce or consume XDMF data.
Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF.
==XML==
The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites.
There are numerous open source parsers available for XML.
The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality.
Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules.
It it case sensitive and is made of three major components: elements, entities, and processing information.
In XDMF the '''element''' is the most important component.
Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''.
===Elements===
Elements follow the basic form:
<pre lang="xml" line="1">
<ElementTag
AttributeName="AttributeValue"
AttributeName="AttributeValue"
... >
CData
</ElementTag>
</pre>
Each element begins with a <tag> and ends with a </tag>.
Optionally there can be several "Name=Value" pairs which convey additional information.
Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData).
CData is typically where the values are stored; like the actual text in an HTML document.
The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents.
This tree can be queried, modified, and then "serialized" back into XML.
Comments in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->.
XML is said to be "well formed" if it is syntactically correct.
That means all of the quotes match, all elements have end elements, etc.
XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document.
For example, the schema might specify that element type A can contain element B but not element C.
Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser.
===XInclude===
As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML.
This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :
<pre lang="xml" line="1">
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<xi:include href="Example3.xmf"/>
</Xdmf>
</pre>
the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.
===XPath===
This allows for elements in the XML document and the API to reference specific elements in a document.
For example:
The first Grid in the first Domain
<pre>
/Xdmf/Domain/Grid
</pre>
The tenth Grid .... XPath is one based.
<pre>
/Xdmf/Domain/Grid[10]
</pre>
The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"''
<pre>
/Xdmf/Domain/Grid[@Name="Copper Plate"]
</pre>
All valid XDMF must appear between the <Xdmf> and the </Xdmf> tags.
So a minimal (empty) XDMF XML file would be:
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0">
</Xdmf>
</pre>
While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers.
For performance reasons, validation is typically disabled.
===Entities===
In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable.
For instance, once an entity alias has been defined in the header via
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [
<!ENTITY cellDimsZYX "45 30 120">
]>
</pre>
the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document.
==XDMF Elements==
The organization of XDMF begins with the ''Xdmf'' element.
So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0).
Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute.
The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later).
Xdmf elements contain one or more ''Domain'' elements (computational domain).
There is seldom motivation to have more than one Domain.
A Domain can have one or more ''Grid'' elements.
Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements.
Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes.
Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center.
To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element.
A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file).
===XdmfItem===
There are six different types of DataItems :
# '''Uniform''' - this is the default. A single array of values.
# '''Collection''' - a one dimension array of DataItems
# '''Tree''' - a hierarchical structure of DataItems
# '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem.
# '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem.
# '''Function''' - calculates an expression.
====Uniform====
The simplest type is Uniform that specifies a single array.
As with all XDMF elements, there are reasonable defaults wherever possible.
So the simplest DataItem would be :
<pre lang="xml" line="1">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
</pre>
Since no ''ItemType'' has been specified, Uniform has been assumed.
The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value.
So the fully qualified DataItem for the same data would be:
<pre lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="XML"
NumberType="Float"
Precision="4"
Rank="1"
Dimensions="3">
1.0 2.0 3.0
</DataItem>
</pre>
Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML.
HDF5 is a hierarchical, self describing data format.
So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file.
XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements.
For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be :
<pre lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</pre>
Alternatively, an application may store its data in binary files.
In this case the XML might be.
<pre lang="xml" line="1">
<DataItem ItemType="Uniform"
Format="Binary"
Dimensions="64 128 256">
PressureFile.bin
</DataItem>
</pre>
Dimensions are specified with the slowest varying dimension first (i.e. KJI order).
The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file.
====Collection and Tree====
Collections are Trees with only a single level.
This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access.
Collections and Trees have DataItem elements as children.
The leaf nodes are Uniform DataItem elements:
<pre lang="xml" line="1">
<DataItem Name="Tree Example" ItemType="Tree">
<DataItem ItemType="Tree">
<DataItem Name="Collection 1" ItemType="Collection">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="4">
4 5 6 7
</DataItem>
</DataItem>
</DataItem>
<DataItem Name="Collection 2" ItemType="Collection">
<DataItem Dimensions="3">
7 8 9
</DataItem>
<DataItem Dimensions="4">
10 11 12 13
</DataItem>
</DataItem>
<DataItem ItemType="Uniform"
Format="HDF"
NumberType="Float"
Precision="8"
Dimensions="64 128 256">
OutputData.h5:/Results/Iteration 100/Part 2/Pressure
</DataItem>
</DataItem>
</pre>
This DataItem is a tree with three children.
The first child is another tree that contains a collection of two uniform DataItem elements.
The second child is a collection with two uniform DataItem elements.
The third child is a uniform DataItem.
====HyperSlab====
A ''HyperSlab'' specifies a subset of some other DataItem.
The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions.
For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem
<pre lang="xml" line="1">
<DataItem ItemType="HyperSlab"
Dimensions="25 50 75 3"
Type="HyperSlab">
<DataItem Dimensions="3 4"
Format="XML">
0 0 0 0
2 2 2 1
25 50 75 3
</DataItem>
<DataItem
Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</pre>
Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem.
====Coordinate====
Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value.
This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType.
<pre lang="xml" line="1">
<DataItem ItemType="Coordinate"
Dimensions="2"
Type="Coordinate">
<DataItem Dimensions="2 4"
Format="XML">
0 0 0 1
99 199 299 0
</DataItem>
<DataItem Name="Points"
Dimensions="100 200 300 3"
Format="HDF">
MyData.h5:/XYZ
</DataItem>
</DataItem>
</pre>
The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem.
====Function====
''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 :
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0 + $1"
Dimensions="3">
<DataItem Dimensions="3">
1.0 2.0 3.0
</DataItem>
<DataItem Dimensions="3">
4.1 5.2 6.3
</DataItem>
</DataItem>
</pre>
The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified :
Add the value 10 to every element
<pre lang="xml" line="1">
<DataItem Name="MyFunction"
ItemType="Function"
Function="10 + $0">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</pre>
Multiply two arrays (element by element) and take the absolute value
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="ABS($0 * $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</pre>
Select element 5 thru 15 from the first DataItem
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="$0[5:15]">
<DataItem Reference="/Xdmf/DataItem[1]" />
</DataItem>
</pre>
Concatenate two arrays
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 ; $1)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
</DataItem>
</pre>
Interlace 3 arrays (Useful for describing vectors from scalar data)
<pre lang="xml" line="1">
<DataItem ItemType="Function"
Function="JOIN($0 , $1, $2)">
<DataItem Reference="/Xdmf/DataItem[1]" />
<DataItem Reference="/Xdmf/DataItem[2]" />
<DataItem Reference="/Xdmf/DataItem[3]" />
</DataItem>
</pre>
===Grid===
The DataItem element is used to define the data format portion of XDMF.
It is sufficient to specify fairly complex data structures in a portable manner.
The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values.
The Grid element now has a GridType attribute. Valid GridTypes are :
# '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles)
# '''Collection''' - an array of Uniform grids all with the same Attributes
# '''Tree''' - a hierarchical group
# '''SubSet ''' - a portion of another Grid
====Uniform, Collection, and Tree====
Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element.
If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal".
Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children:
<pre lang="xml" line="1">
<Grid Name="Car Wheel" GridType="Tree">
<Grid Name="Tire" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nuts" GridType="Collection">
<Grid Name="Lug Nut 0" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 1" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
<Grid Name="Lug Nut 2" GridType="Uniform">
<Topology> ... </Topology>
<Geometry> ... </Geometry>
</Grid>
</Grid>
.
.
.
</pre>
====SubSet====
A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' :
<pre lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="DataItem">
<!-- Select 2 cells from another grid.
Which 2 are defined by the DataItem -->
<DataItem
DataType="Int"
Dimensions="2"
Format="XML">
0 2
</DataItem>
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="2">
100 150
</DataItem>
</Attribute>
</Grid>
</pre>
Or
<pre lang="xml" line="1">
<Grid Name="Portion" GridType="Subset" Section="All">
<!-- Select the entire grid and add an attribute -->
<Grid Name="Target" Reference="XML">
/Xdmf/Domain/Grid[@Name="Main Grid"]
</Grid>
<Attribute Name="New Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
100 150 200
</DataItem>
</Attribute>
</Grid>
</pre>
===Topology===
The Topology element describes the general organization of the data.
This is the part of the computational grid that is invariant with rotation, translation, and scale.
For structured grids, the connectivity is implicit.
For unstructured grids, if the connectivity differs from the standard, an Order may be specified.
Currently, the following Topology cell types are defined :
[[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]]
====Linear====
* Polyvertex - a group of unconnected points
* Polyline - a group of line segments
* Polygon
* Triangle
* Quadrilateral
* Tetrahedron
* Pyramid
* Wedge
* Hexahedron
====Quadratic====
* Edge_3 - Quadratic line with 3 nodes
* Tri_6
* Quad_8
* Tet_10
* Pyramid_13
* Wedge_15
* Hex_20
====Arbitrary====
Mixed topology enables to define a mixture of unstructured cells (see picture to right).
A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell.
Cell types can be:
* 1 - POLYVERTEX
* 2 - POLYLINE
* 3 - POLYGON
* 4 - TRIANGLE
* 5 - QUADRILATERAL
* 6 - TETRAHEDRON
* 7 - PYRAMID
* 8 - WEDGE
* 9 - HEXAHEDRON
* 16 - POLYHEDRON
* 34 - EDGE_3
* 35 - QUADRILATERAL_9
* 36 - TRIANGLE_6
* 37 - QUADRILATERAL_8
* 38 - TETRAHEDRON_10
* 39 - PYRAMID_13
* 40 - WEDGE_15
* 41 - WEDGE_18
* 48 - HEXAHEDRON_20
* 49 - HEXAHEDRON_24
* 50 - HEXAHEDRON_27
The list of data describing each cell depends on the cell type.
If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell.
If the cell is a polygon, the list of data describing each polygon is:
* number of nodes the polygon is made of
* the (ordered) list of each index of each node
If the cell is a polyhedron, the list of data describing each polyhedron is:
* number of faces the polyhedron is made of
* for each face: the number of nodes of the face, and, the (ordered) list of each index of each node
Here is an example of an octahedron (polyhedron):
<pre lang="xml" line="1">
<Domain>
<Grid Name="Octahedron" GridType="Uniform">
<Topology TopologyType="Mixed">
<DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML">
<!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices -->
16
8
3 0 1 4
3 0 1 5
3 1 2 4
3 1 2 5
3 2 3 4
3 2 3 5
3 3 0 4
3 3 0 5
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML">
-1. -1. 0.
-1. 1. 0.
1. 1. 0.
1. -1. 0.
0. 0. 1.
0. 0. -1.
</DataItem>
</Geometry>
</Grid>
</Domain>
</pre>
====Structured====
* 2DSMesh - Curvilinear
* 2DRectMesh - Axis are perpendicular
* 2DCoRectMesh - Axis are perpendicular and spacing is constant
* 3DSMesh
* 3DRectMesh
* 3DCoRectMesh
There is a ''NodesPerElement'' attribute for the cell types where it is not implicit.
For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8".
For structured grid topologies, the connectivity is implicit.
For unstructured topologies the Topology element must contain a DataItem that defines the connectivity:
<pre lang="xml" line="1">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
</pre>
The connectivity defines the indexes into the XYZ geometry that define the cell.
In this example, the two quads share an edge defined by the line from node 1 to node 2.
A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity.
Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions
denotes the total number of items used to describe the topology (total of 20).
Mixed topologies must define the cell type of every element.
If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how
many node points are needed to define the shape.
In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9):
<pre lang="xml" line="1">
<Topology TopologyType="Mixed" NumberOfElements="3" >
<DataItem Format="XML" DataType="Int" Dimensions="20">
6 0 1 2 7
3 4 4 5 6 7
9 8 9 10 11 12 13 14 15
</DataItem>
</Topology>
</pre>
Notice that the Polygon must define the number of nodes (4) before its connectivity.
The cell type numbers are defined in the API documentation.
The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3.
===Geometry===
The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are :
* '''XYZ''' - Interlaced locations
* '''XY''' - Z is set to 0.0
* '''X_Y_Z''' - X,Y, and Z are separate arrays
* '''VXVYVZ''' - Three arrays, one for each axis
* '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz
* '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy
The following Geometry element defines 8 points :
<pre lang="xml" line="1">
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</pre>
Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used):
[[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]]
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<Grid Name="Two Quads">
<Topology TopologyType="Quadrilateral" NumberOfElements="2">
<DataItem Format="XML" DataType="Int" Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</pre>
It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements.
This could be useful if several Grids share the same Geometry but have separate Topology:
[[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]]
<pre lang="xml" line="1">
<?xml version="1.0" ?>
<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []>
<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]">
<Domain>
<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">
0.0 0.0 0.0
1.0 0.0 0.0
1.0 1.0 0.0
0.0 1.0 0.0
0.0 0.0 2.0
1.0 0.0 2.0
1.0 1.0 2.0
0.0 1.0 2.0
</DataItem>
<Grid Name="Two Quads">
<Topology Type="Quadrilateral" NumberOfElements="2" >
<DataItem Format="XML"
DataType="Int"
Dimensions="2 4">
0 1 2 3
1 6 7 2
</DataItem>
</Topology>
<Geometry GeometryType="XYZ">
<DataItem Reference="XML">
/Xdmf/Domain/DataItem[@Name="Point Data"]
</DataItem>
</Geometry>
</Grid>
</Domain>
</Xdmf>
</pre>
===Attribute===
The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh.
'''AttributeType''' specifies a rank of data stored on mesh, it could be one of:
* '''Scalar'''
* '''Vector'''
* '''Tensor''' - 9 values expected
* '''Tensor6''' - a symmetrical tensor
* '''Matrix ''' - an arbitrary NxM matrix
'''Center''' defines where data are centered and it could take values from:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
* '''Grid'''
* '''Other'''
A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid.
Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present).
Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values.
Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other.
'''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType
*'''FiniteElementFunction'''
and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options:
*'''CG'''
*'''DG'''
*'''Q'''
*'''DQ'''
*'''RT'''
and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options:
*'''interval'''
*'''triangle'''
*'''tetrahedron'''
*'''quadrilateral'''
*'''hexahedron'''
Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!):
* indices to degrees of freedom values (in finite element codes also called dofmap)
* degrees of freedom values
First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array.
Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element
theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function.
For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering.
(Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are:
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}'''
* ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}'''
* ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}'''
* ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}'''
VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org).
==== Examples of usage of Attribute:====
Typically simple Attributes are assigned on the Node :
<pre lang="xml" line="1">
<Attribute Name="Node Values" Center="Node">
<DataItem Format="XML" Dimensions="6 4">
100 200 300 400
500 600 600 700
800 900 1000 1100
1200 1300 1400 1500
1600 1700 1800 1900
2000 2100 2200 2300
</DataItem>
</Attribute>
</pre>
Or assigned to the cell centers :
<pre lang="xml" line="1">
<Attribute Name="Cell Values" Center="Cell">
<DataItem Format="XML" Dimensions="3">
3000 2000 1000
</DataItem>
</Attribute>
</pre>
An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh):
<pre lang="xml" line="1">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar">
<DataItem Dimensions="8 3" NumberType="UInt" Format="XML">
3 6 4
3 1 4
6 8 7
6 4 7
1 4 2
1 0 2
4 7 5
4 2 5
</DataItem>
<DataItem Dimensions="9 1" NumberType="Float" Format="XML">
0
0
0.5
0
0.25
1
0
0.5
0
</DataItem>
</Attribute>
</pre>
There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above.
An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh):
<pre lang="xml">
<Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector">
<DataItem Dimensions="8 6" NumberType="UInt" Format="XML">
6 12 8 7 13 9
6 2 8 7 3 9
12 16 14 13 17 15
12 8 14 13 9 15
2 8 4 3 9 5
2 0 4 3 1 5
8 14 10 9 15 11
8 4 10 9 5 11
</DataItem>
<DataItem Dimensions="18 1" NumberType="Float" Format="XML">
0
1
0
0.5
0.5
1
0
0
0.5
0.5
1
1
0.5
0
1
0.5
1
0
</DataItem>
</Attribute>
</pre>
Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5).
===Set===
The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''.
Valid SetTypes are:
* '''Node'''
* '''Edge'''
* '''Face'''
* '''Cell'''
'''Set''' may have multiple DataItems.
The last DataItem always provides the indices of the entity.
If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices.
It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4.
<pre lang="xml" line="1">
<Set Name="Ids" SetType="Face">
<DataItem Format="XML" Dimensions="4" >
1 2 3 4
</DataItem>
<DataItem Format="XML" Dimensions="4" >
0 0 0 0
</DataItem>
<Attribute Name="Example" Center="Face">
<DataItem Format="XML" Dimensions="4" >
100.0 110.0 100.0 200.0
</DataItem>
</Attribute>
</Set>
</pre>
===Time===
The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid.
Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes.
The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are :
* '''Single''' - A single time value for the entire grid
* '''HyperSlab''' - Start, Stride, Count
* '''List''' - A list of discrete times
* '''Range''' - Min, Max
So in the simplest form, specifying a single time:
<pre lang="xml" line="1">
<Time Value="0.1" />
</pre>
For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time:
<pre lang="xml" line="1">
<Time TimeType="HyperSlab">
<DataItem Format="XML" NumberType="Float" Dimensions="3">
0.0 0.000001 100
</DataItem>
</Time>
</pre>
For a collection of grids not written at regular intervals:
<pre lang="xml" line="1">
<Time TimeType="List">
<DataItem Format="XML" NumberType="Float" Dimensions="7">
0.0 0.1 0.5 1.0 1.1 10.0 100.5
</DataItem>
</Time>
</pre>
For data which is valid not at a discrete time but within a range:
<pre lang="xml" line="1">
<Time TimeType="Range">
<DataItem Format="XML" NumberType="Float" Dimensions="2">
0.0 0.5
</DataItem>
</Time>
</pre>
===Information===
There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element:
<pre lang="xml" line="1">
<Information Name="XBounds" Value="0.0 10.0"/>
<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>
</pre>
Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema.
If some of these get used extensively they may be promoted to XDMF elements in the future.
===XML Element (Xdmf ClassName) and Default XML Attributes===
Default values are shown in <span style='color:red'>red</span>.
* Attribute (XdmfAttribute)
Name (no default)
AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID
Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other
ItemType (no default) | FiniteElementFunction
ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction")
ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction")
ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction")
* DataItem (XdmfDataItem)
Name (no default)
ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function
Dimensions (no default) in KJI Order
NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar
Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8
Format <span style='color:red'>XML</span> | HDF | Binary
Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format)
Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration)
Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression)
* Domain (XdmfDomain)
Name (no default)
* Geometry (XdmfGeometry)
GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy
* Grid (XdmfGrid)
Name (no default)
GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset
CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection")
Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset")
* Information (XdmfInformation)
Name (no default)
Value (no default)
* Xdmf (XdmfRoot)
Version <span style='color:red'>Current Version</span> | *
* Topology (XdmfTopology)
Name (no default)
TopologyType Polyvertex | Polyline | Polygon |
Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron |
Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 |
Wedge_15 | Hexahedron_20 |
Mixed |
2DSMesh | 2DRectMesh | 2DCoRectMesh |
3DSMesh | 3DRectMesh | 3DCoRectMesh
NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline
NumberOfElements (no default)
OR
Dimensions (no default)
Order each cell type has its own default
* Time
TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range
Value (no default - Only valid for TimeType="Single")
c6b87ee661b143d4a97024b636204788e483898d